| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ipc/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
| 6 | 6 |
| 7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
| 8 #include "base/files/file.h" | 8 #include "base/files/file.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| 11 #include "base/pickle.h" | 11 #include "base/pickle.h" |
| 12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 13 #include "ipc/ipc_message.h" | 13 #include "ipc/ipc_message.h" |
| 14 #include "ipc/ipc_test_base.h" | 14 #include "ipc/ipc_test_base.h" |
| 15 #include "ipc/ipc_test_channel_listener.h" | 15 #include "ipc/ipc_test_channel_listener.h" |
| 16 #include "ipc/mojo/ipc_channel_mojo_host.h" | 16 #include "ipc/mojo/ipc_channel_mojo_host.h" |
| 17 #include "ipc/mojo/ipc_mojo_handle_attachment.h" |
| 18 #include "ipc/mojo/ipc_mojo_message_helper.h" |
| 17 | 19 |
| 18 #if defined(OS_POSIX) | 20 #if defined(OS_POSIX) |
| 19 #include "base/file_descriptor_posix.h" | 21 #include "base/file_descriptor_posix.h" |
| 20 #include "ipc/ipc_platform_file_attachment_posix.h" | 22 #include "ipc/ipc_platform_file_attachment_posix.h" |
| 21 #endif | 23 #endif |
| 22 | 24 |
| 23 namespace { | 25 namespace { |
| 24 | 26 |
| 25 class ListenerThatExpectsOK : public IPC::Listener { | 27 class ListenerThatExpectsOK : public IPC::Listener { |
| 26 public: | 28 public: |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 base::MessageLoop::current()->Run(); | 252 base::MessageLoop::current()->Run(); |
| 251 | 253 |
| 252 this->channel()->Close(); | 254 this->channel()->Close(); |
| 253 | 255 |
| 254 EXPECT_TRUE(WaitForClientShutdown()); | 256 EXPECT_TRUE(WaitForClientShutdown()); |
| 255 EXPECT_TRUE(listener.has_error()); | 257 EXPECT_TRUE(listener.has_error()); |
| 256 | 258 |
| 257 DestroyChannel(); | 259 DestroyChannel(); |
| 258 } | 260 } |
| 259 | 261 |
| 262 struct TestingMessagePipe { |
| 263 TestingMessagePipe() { |
| 264 EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateMessagePipe(nullptr, &self, &peer)); |
| 265 } |
| 266 |
| 267 mojo::ScopedMessagePipeHandle self; |
| 268 mojo::ScopedMessagePipeHandle peer; |
| 269 }; |
| 270 |
| 271 class HandleSendingHelper { |
| 272 public: |
| 273 static std::string GetSendingFileContent() { return "Hello"; } |
| 274 |
| 275 static void WritePipe(IPC::Message* message, TestingMessagePipe* pipe) { |
| 276 std::string content = HandleSendingHelper::GetSendingFileContent(); |
| 277 EXPECT_EQ(MOJO_RESULT_OK, |
| 278 mojo::WriteMessageRaw(pipe->self.get(), &content[0], |
| 279 static_cast<uint32_t>(content.size()), |
| 280 nullptr, 0, 0)); |
| 281 EXPECT_TRUE( |
| 282 IPC::MojoMessageHelper::WriteMessagePipeTo(message, pipe->peer.Pass())); |
| 283 } |
| 284 |
| 285 static void WritePipeThenSend(IPC::Sender* sender, TestingMessagePipe* pipe) { |
| 286 IPC::Message* message = |
| 287 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); |
| 288 WritePipe(message, pipe); |
| 289 ASSERT_TRUE(sender->Send(message)); |
| 290 } |
| 291 |
| 292 static void ReadReceivedPipe(const IPC::Message& message, |
| 293 PickleIterator* iter) { |
| 294 mojo::ScopedMessagePipeHandle pipe; |
| 295 EXPECT_TRUE( |
| 296 IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe)); |
| 297 std::string content(GetSendingFileContent().size(), ' '); |
| 298 |
| 299 uint32_t num_bytes = static_cast<uint32_t>(content.size()); |
| 300 EXPECT_EQ(MOJO_RESULT_OK, |
| 301 mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr, |
| 302 nullptr, 0)); |
| 303 EXPECT_EQ(content, GetSendingFileContent()); |
| 304 } |
| 305 |
| 306 #if defined(OS_POSIX) |
| 307 static base::FilePath GetSendingFilePath() { |
| 308 base::FilePath path; |
| 309 bool ok = PathService::Get(base::DIR_CACHE, &path); |
| 310 EXPECT_TRUE(ok); |
| 311 return path.Append("ListenerThatExpectsFile.txt"); |
| 312 } |
| 313 |
| 314 static void WriteFile(IPC::Message* message, base::File& file) { |
| 315 std::string content = GetSendingFileContent(); |
| 316 file.WriteAtCurrentPos(content.data(), content.size()); |
| 317 file.Flush(); |
| 318 message->WriteAttachment(new IPC::internal::PlatformFileAttachment( |
| 319 base::ScopedFD(file.TakePlatformFile()))); |
| 320 } |
| 321 |
| 322 static void WriteFileThenSend(IPC::Sender* sender, base::File& file) { |
| 323 IPC::Message* message = |
| 324 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); |
| 325 WriteFile(message, file); |
| 326 ASSERT_TRUE(sender->Send(message)); |
| 327 } |
| 328 |
| 329 static void WriteFileAndPipeThenSend(IPC::Sender* sender, |
| 330 base::File& file, |
| 331 TestingMessagePipe* pipe) { |
| 332 IPC::Message* message = |
| 333 new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); |
| 334 WriteFile(message, file); |
| 335 WritePipe(message, pipe); |
| 336 ASSERT_TRUE(sender->Send(message)); |
| 337 } |
| 338 |
| 339 static void ReadReceivedFile(const IPC::Message& message, |
| 340 PickleIterator* iter) { |
| 341 base::ScopedFD fd; |
| 342 scoped_refptr<IPC::MessageAttachment> attachment; |
| 343 EXPECT_TRUE(message.ReadAttachment(iter, &attachment)); |
| 344 base::File file(attachment->TakePlatformFile()); |
| 345 std::string content(GetSendingFileContent().size(), ' '); |
| 346 file.Read(0, &content[0], content.size()); |
| 347 EXPECT_EQ(content, GetSendingFileContent()); |
| 348 } |
| 349 #endif |
| 350 }; |
| 351 |
| 352 class ListenerThatExpectsMessagePipe : public IPC::Listener { |
| 353 public: |
| 354 ListenerThatExpectsMessagePipe() : sender_(NULL) {} |
| 355 |
| 356 ~ListenerThatExpectsMessagePipe() override {} |
| 357 |
| 358 bool OnMessageReceived(const IPC::Message& message) override { |
| 359 PickleIterator iter(message); |
| 360 HandleSendingHelper::ReadReceivedPipe(message, &iter); |
| 361 base::MessageLoop::current()->Quit(); |
| 362 ListenerThatExpectsOK::SendOK(sender_); |
| 363 return true; |
| 364 } |
| 365 |
| 366 void OnChannelError() override { NOTREACHED(); } |
| 367 |
| 368 void set_sender(IPC::Sender* sender) { sender_ = sender; } |
| 369 |
| 370 private: |
| 371 IPC::Sender* sender_; |
| 372 }; |
| 373 |
| 374 TEST_F(IPCChannelMojoTest, SendMessagePipe) { |
| 375 Init("IPCChannelMojoTestSendMessagePipeClient"); |
| 376 |
| 377 ListenerThatExpectsOK listener; |
| 378 CreateChannel(&listener); |
| 379 ASSERT_TRUE(ConnectChannel()); |
| 380 ASSERT_TRUE(StartClient()); |
| 381 |
| 382 TestingMessagePipe pipe; |
| 383 HandleSendingHelper::WritePipeThenSend(channel(), &pipe); |
| 384 |
| 385 base::MessageLoop::current()->Run(); |
| 386 this->channel()->Close(); |
| 387 |
| 388 EXPECT_TRUE(WaitForClientShutdown()); |
| 389 DestroyChannel(); |
| 390 } |
| 391 |
| 392 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendMessagePipeClient) { |
| 393 ListenerThatExpectsMessagePipe listener; |
| 394 ChannelClient client(&listener, "IPCChannelMojoTestSendPlatformHandleClient"); |
| 395 client.Connect(); |
| 396 listener.set_sender(client.channel()); |
| 397 |
| 398 base::MessageLoop::current()->Run(); |
| 399 |
| 400 return 0; |
| 401 } |
| 402 |
| 260 #if defined(OS_WIN) | 403 #if defined(OS_WIN) |
| 261 class IPCChannelMojoDeadHandleTest : public IPCTestBase { | 404 class IPCChannelMojoDeadHandleTest : public IPCTestBase { |
| 262 protected: | 405 protected: |
| 263 virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( | 406 virtual scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( |
| 264 const IPC::ChannelHandle& handle, | 407 const IPC::ChannelHandle& handle, |
| 265 base::TaskRunner* runner) override { | 408 base::TaskRunner* runner) override { |
| 266 host_.reset(new IPC::ChannelMojoHost(task_runner())); | 409 host_.reset(new IPC::ChannelMojoHost(task_runner())); |
| 267 return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(), | 410 return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(), |
| 268 handle); | 411 handle); |
| 269 } | 412 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 #if defined(OS_POSIX) | 463 #if defined(OS_POSIX) |
| 321 class ListenerThatExpectsFile : public IPC::Listener { | 464 class ListenerThatExpectsFile : public IPC::Listener { |
| 322 public: | 465 public: |
| 323 ListenerThatExpectsFile() | 466 ListenerThatExpectsFile() |
| 324 : sender_(NULL) {} | 467 : sender_(NULL) {} |
| 325 | 468 |
| 326 ~ListenerThatExpectsFile() override {} | 469 ~ListenerThatExpectsFile() override {} |
| 327 | 470 |
| 328 bool OnMessageReceived(const IPC::Message& message) override { | 471 bool OnMessageReceived(const IPC::Message& message) override { |
| 329 PickleIterator iter(message); | 472 PickleIterator iter(message); |
| 330 | 473 HandleSendingHelper::ReadReceivedFile(message, &iter); |
| 331 base::ScopedFD fd; | |
| 332 scoped_refptr<IPC::MessageAttachment> attachment; | |
| 333 EXPECT_TRUE(message.ReadAttachment(&iter, &attachment)); | |
| 334 base::File file(attachment->TakePlatformFile()); | |
| 335 std::string content(GetSendingFileContent().size(), ' '); | |
| 336 file.Read(0, &content[0], content.size()); | |
| 337 EXPECT_EQ(content, GetSendingFileContent()); | |
| 338 base::MessageLoop::current()->Quit(); | 474 base::MessageLoop::current()->Quit(); |
| 339 ListenerThatExpectsOK::SendOK(sender_); | 475 ListenerThatExpectsOK::SendOK(sender_); |
| 340 return true; | 476 return true; |
| 341 } | 477 } |
| 342 | 478 |
| 343 void OnChannelError() override { | 479 void OnChannelError() override { |
| 344 NOTREACHED(); | 480 NOTREACHED(); |
| 345 } | 481 } |
| 346 | 482 |
| 347 static std::string GetSendingFileContent() { | |
| 348 return "Hello"; | |
| 349 } | |
| 350 | |
| 351 static base::FilePath GetSendingFilePath() { | |
| 352 base::FilePath path; | |
| 353 bool ok = PathService::Get(base::DIR_CACHE, &path); | |
| 354 EXPECT_TRUE(ok); | |
| 355 return path.Append("ListenerThatExpectsFile.txt"); | |
| 356 } | |
| 357 | |
| 358 static void WriteAndSendFile(IPC::Sender* sender, base::File& file) { | |
| 359 std::string content = GetSendingFileContent(); | |
| 360 file.WriteAtCurrentPos(content.data(), content.size()); | |
| 361 file.Flush(); | |
| 362 IPC::Message* message = new IPC::Message( | |
| 363 0, 2, IPC::Message::PRIORITY_NORMAL); | |
| 364 message->WriteAttachment(new IPC::internal::PlatformFileAttachment( | |
| 365 base::ScopedFD(file.TakePlatformFile()))); | |
| 366 ASSERT_TRUE(sender->Send(message)); | |
| 367 } | |
| 368 | |
| 369 void set_sender(IPC::Sender* sender) { sender_ = sender; } | 483 void set_sender(IPC::Sender* sender) { sender_ = sender; } |
| 370 | 484 |
| 371 private: | 485 private: |
| 372 IPC::Sender* sender_; | 486 IPC::Sender* sender_; |
| 373 }; | 487 }; |
| 374 | 488 |
| 375 | 489 |
| 376 TEST_F(IPCChannelMojoTest, SendPlatformHandle) { | 490 TEST_F(IPCChannelMojoTest, SendPlatformHandle) { |
| 377 Init("IPCChannelMojoTestSendPlatformHandleClient"); | 491 Init("IPCChannelMojoTestSendPlatformHandleClient"); |
| 378 | 492 |
| 379 ListenerThatExpectsOK listener; | 493 ListenerThatExpectsOK listener; |
| 380 CreateChannel(&listener); | 494 CreateChannel(&listener); |
| 381 ASSERT_TRUE(ConnectChannel()); | 495 ASSERT_TRUE(ConnectChannel()); |
| 382 ASSERT_TRUE(StartClient()); | 496 ASSERT_TRUE(StartClient()); |
| 383 | 497 |
| 384 base::File file(ListenerThatExpectsFile::GetSendingFilePath(), | 498 base::File file(HandleSendingHelper::GetSendingFilePath(), |
| 385 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | | 499 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | |
| 386 base::File::FLAG_READ); | 500 base::File::FLAG_READ); |
| 387 ListenerThatExpectsFile::WriteAndSendFile(channel(), file); | 501 HandleSendingHelper::WriteFileThenSend(channel(), file); |
| 388 base::MessageLoop::current()->Run(); | 502 base::MessageLoop::current()->Run(); |
| 389 | 503 |
| 390 this->channel()->Close(); | 504 this->channel()->Close(); |
| 391 | 505 |
| 392 EXPECT_TRUE(WaitForClientShutdown()); | 506 EXPECT_TRUE(WaitForClientShutdown()); |
| 393 DestroyChannel(); | 507 DestroyChannel(); |
| 394 } | 508 } |
| 395 | 509 |
| 396 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendPlatformHandleClient) { | 510 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendPlatformHandleClient) { |
| 397 ListenerThatExpectsFile listener; | 511 ListenerThatExpectsFile listener; |
| 398 ChannelClient client( | 512 ChannelClient client( |
| 399 &listener, "IPCChannelMojoTestSendPlatformHandleClient"); | 513 &listener, "IPCChannelMojoTestSendPlatformHandleClient"); |
| 400 client.Connect(); | 514 client.Connect(); |
| 401 listener.set_sender(client.channel()); | 515 listener.set_sender(client.channel()); |
| 402 | 516 |
| 403 base::MessageLoop::current()->Run(); | 517 base::MessageLoop::current()->Run(); |
| 404 | 518 |
| 405 return 0; | 519 return 0; |
| 406 } | 520 } |
| 521 |
| 522 class ListenerThatExpectsFileAndPipe : public IPC::Listener { |
| 523 public: |
| 524 ListenerThatExpectsFileAndPipe() : sender_(NULL) {} |
| 525 |
| 526 ~ListenerThatExpectsFileAndPipe() override {} |
| 527 |
| 528 bool OnMessageReceived(const IPC::Message& message) override { |
| 529 PickleIterator iter(message); |
| 530 HandleSendingHelper::ReadReceivedFile(message, &iter); |
| 531 HandleSendingHelper::ReadReceivedPipe(message, &iter); |
| 532 base::MessageLoop::current()->Quit(); |
| 533 ListenerThatExpectsOK::SendOK(sender_); |
| 534 return true; |
| 535 } |
| 536 |
| 537 void OnChannelError() override { NOTREACHED(); } |
| 538 |
| 539 void set_sender(IPC::Sender* sender) { sender_ = sender; } |
| 540 |
| 541 private: |
| 542 IPC::Sender* sender_; |
| 543 }; |
| 544 |
| 545 TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) { |
| 546 Init("IPCChannelMojoTestSendPlatformHandleAndPipeClient"); |
| 547 |
| 548 ListenerThatExpectsOK listener; |
| 549 CreateChannel(&listener); |
| 550 ASSERT_TRUE(ConnectChannel()); |
| 551 ASSERT_TRUE(StartClient()); |
| 552 |
| 553 base::File file(HandleSendingHelper::GetSendingFilePath(), |
| 554 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | |
| 555 base::File::FLAG_READ); |
| 556 TestingMessagePipe pipe; |
| 557 HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe); |
| 558 |
| 559 base::MessageLoop::current()->Run(); |
| 560 this->channel()->Close(); |
| 561 |
| 562 EXPECT_TRUE(WaitForClientShutdown()); |
| 563 DestroyChannel(); |
| 564 } |
| 565 |
| 566 MULTIPROCESS_IPC_TEST_CLIENT_MAIN( |
| 567 IPCChannelMojoTestSendPlatformHandleAndPipeClient) { |
| 568 ListenerThatExpectsFileAndPipe listener; |
| 569 ChannelClient client(&listener, |
| 570 "IPCChannelMojoTestSendPlatformHandleAndPipeClient"); |
| 571 client.Connect(); |
| 572 listener.set_sender(client.channel()); |
| 573 |
| 574 base::MessageLoop::current()->Run(); |
| 575 |
| 576 return 0; |
| 577 } |
| 578 |
| 407 #endif | 579 #endif |
| 408 | 580 |
| 409 } // namespace | 581 } // namespace |
| OLD | NEW |