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 |