| 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/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "ipc/ipc_listener.h" | 10 #include "ipc/ipc_listener.h" |
| 11 #include "ipc/mojo/ipc_mojo_bootstrap.h" |
| 11 #include "mojo/embedder/embedder.h" | 12 #include "mojo/embedder/embedder.h" |
| 12 | 13 |
| 13 #if defined(OS_POSIX) && !defined(OS_NACL) | 14 #if defined(OS_POSIX) && !defined(OS_NACL) |
| 14 #include "ipc/file_descriptor_set_posix.h" | 15 #include "ipc/file_descriptor_set_posix.h" |
| 15 #endif | 16 #endif |
| 16 | 17 |
| 17 namespace IPC { | 18 namespace IPC { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 33 | 34 |
| 34 virtual void OnChannelError() OVERRIDE { | 35 virtual void OnChannelError() OVERRIDE { |
| 35 NOTREACHED(); | 36 NOTREACHED(); |
| 36 } | 37 } |
| 37 | 38 |
| 38 virtual void OnBadMessageReceived(const Message& message) OVERRIDE { | 39 virtual void OnBadMessageReceived(const Message& message) OVERRIDE { |
| 39 NOTREACHED(); | 40 NOTREACHED(); |
| 40 } | 41 } |
| 41 }; | 42 }; |
| 42 | 43 |
| 43 base::LazyInstance<NullListener> g_null_listener = LAZY_INSTANCE_INITIALIZER; | |
| 44 | |
| 45 class MojoChannelFactory : public ChannelFactory { | 44 class MojoChannelFactory : public ChannelFactory { |
| 46 public: | 45 public: |
| 47 MojoChannelFactory( | 46 MojoChannelFactory( |
| 48 ChannelHandle channel_handle, | 47 ChannelHandle channel_handle, |
| 49 Channel::Mode mode, | 48 Channel::Mode mode, |
| 50 scoped_refptr<base::TaskRunner> io_thread_task_runner) | 49 scoped_refptr<base::TaskRunner> io_thread_task_runner) |
| 51 : channel_handle_(channel_handle), | 50 : channel_handle_(channel_handle), |
| 52 mode_(mode), | 51 mode_(mode), |
| 53 io_thread_task_runner_(io_thread_task_runner) { | 52 io_thread_task_runner_(io_thread_task_runner) { |
| 54 } | 53 } |
| 55 | 54 |
| 56 virtual std::string GetName() const OVERRIDE { | 55 virtual std::string GetName() const OVERRIDE { |
| 57 return channel_handle_.name; | 56 return channel_handle_.name; |
| 58 } | 57 } |
| 59 | 58 |
| 60 virtual scoped_ptr<Channel> BuildChannel(Listener* listener) OVERRIDE { | 59 virtual scoped_ptr<Channel> BuildChannel(Listener* listener) OVERRIDE { |
| 61 return ChannelMojo::Create( | 60 return ChannelMojo::Create( |
| 62 channel_handle_, | 61 channel_handle_, |
| 63 mode_, | 62 mode_, |
| 64 listener, | 63 listener, |
| 65 io_thread_task_runner_).PassAs<Channel>(); | 64 io_thread_task_runner_).PassAs<Channel>(); |
| 66 } | 65 } |
| 67 | 66 |
| 68 private: | 67 private: |
| 69 ChannelHandle channel_handle_; | 68 ChannelHandle channel_handle_; |
| 70 Channel::Mode mode_; | 69 Channel::Mode mode_; |
| 71 scoped_refptr<base::TaskRunner> io_thread_task_runner_; | 70 scoped_refptr<base::TaskRunner> io_thread_task_runner_; |
| 72 }; | 71 }; |
| 73 | 72 |
| 74 mojo::embedder::PlatformHandle ToPlatformHandle( | |
| 75 const ChannelHandle& handle) { | |
| 76 #if defined(OS_POSIX) && !defined(OS_NACL) | |
| 77 return mojo::embedder::PlatformHandle(handle.socket.fd); | |
| 78 #elif defined(OS_WIN) | |
| 79 return mojo::embedder::PlatformHandle(handle.pipe.handle); | |
| 80 #else | |
| 81 #error "Unsupported Platform!" | |
| 82 #endif | |
| 83 } | |
| 84 | |
| 85 //------------------------------------------------------------------------------ | 73 //------------------------------------------------------------------------------ |
| 86 | 74 |
| 87 // TODO(morrita): This should be built using higher-level Mojo construct | 75 // TODO(morrita): This should be built using higher-level Mojo construct |
| 88 // for clarity and extensibility. | 76 // for clarity and extensibility. |
| 89 class HelloMessage { | 77 class HelloMessage { |
| 90 public: | 78 public: |
| 91 static Pickle CreateRequest(int32 pid) { | 79 static Pickle CreateRequest(int32 pid) { |
| 92 Pickle request; | 80 Pickle request; |
| 93 request.WriteString(kHelloRequestMagic); | 81 request.WriteString(kHelloRequestMagic); |
| 94 request.WriteInt(pid); | 82 request.WriteInt(pid); |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 mojo::embedder::ChannelInfo* ptr) const { | 439 mojo::embedder::ChannelInfo* ptr) const { |
| 452 mojo::embedder::DestroyChannelOnIOThread(ptr); | 440 mojo::embedder::DestroyChannelOnIOThread(ptr); |
| 453 } | 441 } |
| 454 | 442 |
| 455 //------------------------------------------------------------------------------ | 443 //------------------------------------------------------------------------------ |
| 456 | 444 |
| 457 // static | 445 // static |
| 458 scoped_ptr<ChannelMojo> ChannelMojo::Create( | 446 scoped_ptr<ChannelMojo> ChannelMojo::Create( |
| 459 const ChannelHandle &channel_handle, Mode mode, Listener* listener, | 447 const ChannelHandle &channel_handle, Mode mode, Listener* listener, |
| 460 scoped_refptr<base::TaskRunner> io_thread_task_runner) { | 448 scoped_refptr<base::TaskRunner> io_thread_task_runner) { |
| 461 return make_scoped_ptr(new ChannelMojo( | 449 return make_scoped_ptr( |
| 462 Channel::Create(channel_handle, mode, g_null_listener.Pointer()), | 450 new ChannelMojo(channel_handle, mode, listener, io_thread_task_runner)); |
| 463 mode, listener, io_thread_task_runner)); | |
| 464 } | 451 } |
| 465 | 452 |
| 466 // static | 453 // static |
| 467 scoped_ptr<ChannelFactory> ChannelMojo::CreateFactory( | 454 scoped_ptr<ChannelFactory> ChannelMojo::CreateFactory( |
| 468 const ChannelHandle &channel_handle, Mode mode, | 455 const ChannelHandle &channel_handle, Mode mode, |
| 469 scoped_refptr<base::TaskRunner> io_thread_task_runner) { | 456 scoped_refptr<base::TaskRunner> io_thread_task_runner) { |
| 470 return make_scoped_ptr( | 457 return make_scoped_ptr( |
| 471 new MojoChannelFactory( | 458 new MojoChannelFactory( |
| 472 channel_handle, mode, | 459 channel_handle, mode, |
| 473 io_thread_task_runner)).PassAs<ChannelFactory>(); | 460 io_thread_task_runner)).PassAs<ChannelFactory>(); |
| 474 } | 461 } |
| 475 | 462 |
| 476 ChannelMojo::ChannelMojo( | 463 ChannelMojo::ChannelMojo(ChannelHandle handle, |
| 477 scoped_ptr<Channel> bootstrap, Mode mode, Listener* listener, | 464 Mode mode, |
| 478 scoped_refptr<base::TaskRunner> io_thread_task_runner) | 465 Listener* listener, |
| 479 : bootstrap_(bootstrap.Pass()), | 466 scoped_refptr<base::TaskRunner> io_thread_task_runner) |
| 480 mode_(mode), listener_(listener), | 467 : mode_(mode), |
| 468 listener_(listener), |
| 481 peer_pid_(base::kNullProcessId), | 469 peer_pid_(base::kNullProcessId), |
| 482 weak_factory_(this) { | 470 weak_factory_(this) { |
| 483 if (base::MessageLoopProxy::current() == io_thread_task_runner.get()) { | 471 if (base::MessageLoopProxy::current() == io_thread_task_runner.get()) { |
| 484 InitOnIOThread(); | 472 InitBootstrap(handle); |
| 485 } else { | 473 } else { |
| 486 io_thread_task_runner->PostTask(FROM_HERE, | 474 io_thread_task_runner->PostTask( |
| 487 base::Bind(&ChannelMojo::InitOnIOThread, | 475 FROM_HERE, |
| 488 weak_factory_.GetWeakPtr())); | 476 base::Bind( |
| 477 &ChannelMojo::InitBootstrap, weak_factory_.GetWeakPtr(), handle)); |
| 489 } | 478 } |
| 490 } | 479 } |
| 491 | 480 |
| 492 ChannelMojo::~ChannelMojo() { | 481 ChannelMojo::~ChannelMojo() { |
| 493 Close(); | 482 Close(); |
| 494 } | 483 } |
| 495 | 484 |
| 496 void ChannelMojo::InitOnIOThread() { | 485 void ChannelMojo::InitBootstrap(ChannelHandle handle) { |
| 486 DCHECK(base::MessageLoopForIO::IsCurrent()); |
| 487 bootstrap_ = MojoBootstrap::Create(handle, mode_, this); |
| 488 } |
| 489 |
| 490 void ChannelMojo::InitControlReader( |
| 491 mojo::embedder::ScopedPlatformHandle handle) { |
| 492 DCHECK(base::MessageLoopForIO::IsCurrent()); |
| 497 mojo::embedder::ChannelInfo* channel_info; | 493 mojo::embedder::ChannelInfo* channel_info; |
| 498 mojo::ScopedMessagePipeHandle control_pipe = | 494 mojo::ScopedMessagePipeHandle control_pipe = |
| 499 mojo::embedder::CreateChannelOnIOThread( | 495 mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info); |
| 500 mojo::embedder::ScopedPlatformHandle( | |
| 501 ToPlatformHandle(bootstrap_->TakePipeHandle())), | |
| 502 &channel_info); | |
| 503 channel_info_.reset(channel_info); | 496 channel_info_.reset(channel_info); |
| 504 | 497 |
| 505 switch (mode_) { | 498 switch (mode_) { |
| 506 case MODE_SERVER: | 499 case MODE_SERVER: |
| 507 control_reader_.reset(new ServerControlReader(control_pipe.Pass(), this)); | 500 control_reader_.reset(new ServerControlReader(control_pipe.Pass(), this)); |
| 508 break; | 501 break; |
| 509 case MODE_CLIENT: | 502 case MODE_CLIENT: |
| 510 control_reader_.reset(new ClientControlReader(control_pipe.Pass(), this)); | 503 control_reader_.reset(new ClientControlReader(control_pipe.Pass(), this)); |
| 511 break; | 504 break; |
| 512 default: | 505 default: |
| 513 NOTREACHED(); | 506 NOTREACHED(); |
| 514 break; | 507 break; |
| 515 } | 508 } |
| 516 } | 509 } |
| 517 | 510 |
| 518 bool ChannelMojo::Connect() { | 511 bool ChannelMojo::Connect() { |
| 519 DCHECK(!message_reader_); | 512 DCHECK(!message_reader_); |
| 520 return control_reader_->Connect(); | 513 DCHECK(!control_reader_); |
| 514 return bootstrap_->Connect(); |
| 521 } | 515 } |
| 522 | 516 |
| 523 void ChannelMojo::Close() { | 517 void ChannelMojo::Close() { |
| 524 control_reader_.reset(); | 518 control_reader_.reset(); |
| 525 message_reader_.reset(); | 519 message_reader_.reset(); |
| 526 channel_info_.reset(); | 520 channel_info_.reset(); |
| 527 } | 521 } |
| 528 | 522 |
| 523 void ChannelMojo::OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) { |
| 524 InitControlReader(handle.Pass()); |
| 525 control_reader_->Connect(); |
| 526 } |
| 527 |
| 528 void ChannelMojo::OnBootstrapError() { |
| 529 listener_->OnChannelError(); |
| 530 } |
| 531 |
| 529 void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { | 532 void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { |
| 530 message_reader_ = make_scoped_ptr(new MessageReader(pipe.Pass(), this)); | 533 message_reader_ = make_scoped_ptr(new MessageReader(pipe.Pass(), this)); |
| 531 | 534 |
| 532 for (size_t i = 0; i < pending_messages_.size(); ++i) { | 535 for (size_t i = 0; i < pending_messages_.size(); ++i) { |
| 533 message_reader_->Send(make_scoped_ptr(pending_messages_[i])); | 536 message_reader_->Send(make_scoped_ptr(pending_messages_[i])); |
| 534 pending_messages_[i] = NULL; | 537 pending_messages_[i] = NULL; |
| 535 } | 538 } |
| 536 | 539 |
| 537 pending_messages_.clear(); | 540 pending_messages_.clear(); |
| 538 | 541 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 555 } | 558 } |
| 556 | 559 |
| 557 return message_reader_->Send(make_scoped_ptr(message)); | 560 return message_reader_->Send(make_scoped_ptr(message)); |
| 558 } | 561 } |
| 559 | 562 |
| 560 base::ProcessId ChannelMojo::GetPeerPID() const { | 563 base::ProcessId ChannelMojo::GetPeerPID() const { |
| 561 return peer_pid_; | 564 return peer_pid_; |
| 562 } | 565 } |
| 563 | 566 |
| 564 base::ProcessId ChannelMojo::GetSelfPID() const { | 567 base::ProcessId ChannelMojo::GetSelfPID() const { |
| 565 return bootstrap_->GetSelfPID(); | 568 return base::GetCurrentProcId(); |
| 566 } | 569 } |
| 567 | 570 |
| 568 ChannelHandle ChannelMojo::TakePipeHandle() { | 571 ChannelHandle ChannelMojo::TakePipeHandle() { |
| 569 return bootstrap_->TakePipeHandle(); | 572 NOTREACHED(); |
| 573 return ChannelHandle(); |
| 574 } |
| 575 |
| 576 void ChannelMojo::OnClientLaunched(base::ProcessHandle handle) { |
| 577 bootstrap_->OnClientLaunched(handle); |
| 570 } | 578 } |
| 571 | 579 |
| 572 void ChannelMojo::OnMessageReceived(Message& message) { | 580 void ChannelMojo::OnMessageReceived(Message& message) { |
| 573 listener_->OnMessageReceived(message); | 581 listener_->OnMessageReceived(message); |
| 574 if (message.dispatch_error()) | 582 if (message.dispatch_error()) |
| 575 listener_->OnBadMessageReceived(message); | 583 listener_->OnBadMessageReceived(message); |
| 576 } | 584 } |
| 577 | 585 |
| 578 #if defined(OS_POSIX) && !defined(OS_NACL) | 586 #if defined(OS_POSIX) && !defined(OS_NACL) |
| 579 int ChannelMojo::GetClientFileDescriptor() const { | 587 int ChannelMojo::GetClientFileDescriptor() const { |
| 580 return bootstrap_->GetClientFileDescriptor(); | 588 return bootstrap_->GetClientFileDescriptor(); |
| 581 } | 589 } |
| 582 | 590 |
| 583 int ChannelMojo::TakeClientFileDescriptor() { | 591 int ChannelMojo::TakeClientFileDescriptor() { |
| 584 return bootstrap_->TakeClientFileDescriptor(); | 592 return bootstrap_->TakeClientFileDescriptor(); |
| 585 } | 593 } |
| 586 #endif // defined(OS_POSIX) && !defined(OS_NACL) | 594 #endif // defined(OS_POSIX) && !defined(OS_NACL) |
| 587 | 595 |
| 588 } // namespace IPC | 596 } // namespace IPC |
| OLD | NEW |