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