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 |