Index: ipc/mojo/ipc_channel_mojo.cc |
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc |
index bd3ceb58cf8185f9fe3b145c699f9c3c72e42d4b..de79577c59ba46e163ab76cef407bafc2fe330b3 100644 |
--- a/ipc/mojo/ipc_channel_mojo.cc |
+++ b/ipc/mojo/ipc_channel_mojo.cc |
@@ -8,9 +8,11 @@ |
#include "base/bind_helpers.h" |
#include "base/lazy_instance.h" |
#include "ipc/ipc_listener.h" |
+#include "ipc/mojo/client_channel.mojom.h" |
#include "ipc/mojo/ipc_channel_mojo_readers.h" |
#include "ipc/mojo/ipc_mojo_bootstrap.h" |
#include "mojo/edk/embedder/embedder.h" |
+#include "mojo/public/cpp/bindings/error_handler.h" |
#if defined(OS_POSIX) && !defined(OS_NACL) |
#include "ipc/file_descriptor_set_posix.h" |
@@ -41,6 +43,113 @@ class MojoChannelFactory : public ChannelFactory { |
Channel::Mode mode_; |
}; |
+//------------------------------------------------------------------------------ |
+ |
+class ClientChannelMojo |
+ : public ChannelMojo, |
+ public NON_EXPORTED_BASE(mojo::InterfaceImpl<ClientChannel>) { |
+ public: |
+ ClientChannelMojo(ChannelMojo::Delegate* delegate, |
+ const ChannelHandle& handle, |
+ Listener* listener); |
+ |
+ // MojoBootstrap::Delegate implementation |
+ void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; |
+ // InterfaceImpl implementation |
+ void OnConnectionError() override; |
+ // ClientChannel implementation |
+ void InitClientChannel(mojo::ScopedMessagePipeHandle pipe, |
+ int32_t peer_pid) override; |
+}; |
+ |
+ClientChannelMojo::ClientChannelMojo(ChannelMojo::Delegate* delegate, |
+ const ChannelHandle& handle, |
+ Listener* listener) |
+ : ChannelMojo(delegate, handle, Channel::MODE_CLIENT, listener) { |
+} |
+ |
+void ClientChannelMojo::OnPipeAvailable( |
+ mojo::embedder::ScopedPlatformHandle handle) { |
+ mojo::WeakBindToPipe(this, CreateMessagingPipe(handle.Pass())); |
+} |
+ |
+void ClientChannelMojo::OnConnectionError() { |
+ listener()->OnChannelError(); |
+} |
+ |
+void ClientChannelMojo::InitClientChannel(mojo::ScopedMessagePipeHandle pipe, |
+ int32_t peer_pid) { |
+ InitMessageReader(pipe.Pass(), static_cast<base::ProcessId>(peer_pid)); |
+ client()->ClientChannelWasInitialized(GetSelfPID()); |
+} |
+ |
+//------------------------------------------------------------------------------ |
+ |
+class ServerChannelMojo : public ChannelMojo, |
+ public ClientChannelClient, |
+ public mojo::ErrorHandler { |
+ public: |
+ ServerChannelMojo(ChannelMojo::Delegate* delegate, |
+ const ChannelHandle& handle, |
+ Listener* listener); |
+ virtual ~ServerChannelMojo(); |
+ |
+ // MojoBootstrap::Delegate implementation |
+ void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; |
+ // ClientChannelClient implementation |
+ void ClientChannelWasInitialized(int32_t peer_pid) override; |
+ // ErrorHandler implementation |
+ void OnConnectionError() override; |
+ // Channel override |
+ void Close() override; |
+ |
+ private: |
+ mojo::InterfacePtr<ClientChannel> client_channel_; |
+ mojo::ScopedMessagePipeHandle message_pipe_; |
+}; |
+ |
+ServerChannelMojo::ServerChannelMojo(ChannelMojo::Delegate* delegate, |
+ const ChannelHandle& handle, |
+ Listener* listener) |
+ : ChannelMojo(delegate, handle, Channel::MODE_SERVER, listener) { |
+} |
+ |
+ServerChannelMojo::~ServerChannelMojo() { |
+ Close(); |
+} |
+ |
+void ServerChannelMojo::OnPipeAvailable( |
+ mojo::embedder::ScopedPlatformHandle handle) { |
+ mojo::ScopedMessagePipeHandle peer; |
+ MojoResult create_result = |
+ mojo::CreateMessagePipe(NULL, &message_pipe_, &peer); |
viettrungluu
2014/10/24 01:23:46
nullptr
Hajime Morrita
2014/10/24 17:35:11
Done.
|
+ if (MOJO_RESULT_OK != create_result) { |
viettrungluu
2014/10/24 01:23:46
Side note: In Chromium, we usually prefer to write
Hajime Morrita
2014/10/24 17:35:11
My bad habit :-(
Fixed.
|
+ DLOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result; |
+ listener()->OnChannelError(); |
+ return; |
+ } |
+ |
+ client_channel_.Bind(CreateMessagingPipe(handle.Pass())); |
+ client_channel_.set_client(this); |
+ client_channel_.set_error_handler(this); |
+ client_channel_->InitClientChannel(peer.Pass(), |
+ static_cast<int32_t>(GetSelfPID())); |
+} |
+ |
+void ServerChannelMojo::ClientChannelWasInitialized(int32_t peer_pid) { |
+ InitMessageReader(message_pipe_.Pass(), peer_pid); |
+} |
+ |
+void ServerChannelMojo::OnConnectionError() { |
+ listener()->OnChannelError(); |
+} |
+ |
+void ServerChannelMojo::Close() { |
+ client_channel_.reset(); |
+ message_pipe_.reset(); |
+ ChannelMojo::Close(); |
+} |
+ |
} // namespace |
//------------------------------------------------------------------------------ |
@@ -63,8 +172,17 @@ scoped_ptr<ChannelMojo> ChannelMojo::Create(ChannelMojo::Delegate* delegate, |
const ChannelHandle& channel_handle, |
Mode mode, |
Listener* listener) { |
- return make_scoped_ptr( |
- new ChannelMojo(delegate, channel_handle, mode, listener)); |
+ switch (mode) { |
+ case Channel::MODE_CLIENT: |
+ return make_scoped_ptr( |
+ new ClientChannelMojo(delegate, channel_handle, listener)); |
+ case Channel::MODE_SERVER: |
+ return make_scoped_ptr( |
+ new ServerChannelMojo(delegate, channel_handle, listener)); |
+ default: |
+ NOTREACHED(); |
+ return nullptr; |
+ } |
} |
// static |
@@ -115,51 +233,32 @@ void ChannelMojo::InitDelegate(ChannelMojo::Delegate* delegate) { |
delegate_->OnChannelCreated(weak_factory_.GetWeakPtr()); |
} |
-void ChannelMojo::InitControlReader( |
+mojo::ScopedMessagePipeHandle ChannelMojo::CreateMessagingPipe( |
mojo::embedder::ScopedPlatformHandle handle) { |
- DCHECK(base::MessageLoopForIO::IsCurrent()); |
+ DCHECK(!channel_info_.get()); |
mojo::embedder::ChannelInfo* channel_info; |
- mojo::ScopedMessagePipeHandle control_pipe = |
+ mojo::ScopedMessagePipeHandle pipe = |
mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info); |
channel_info_.reset(channel_info); |
- |
- switch (mode_) { |
- case MODE_SERVER: |
- control_reader_.reset( |
- new internal::ServerControlReader(control_pipe.Pass(), this)); |
- break; |
- case MODE_CLIENT: |
- control_reader_.reset( |
- new internal::ClientControlReader(control_pipe.Pass(), this)); |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
+ return pipe.Pass(); |
} |
bool ChannelMojo::Connect() { |
DCHECK(!message_reader_); |
- DCHECK(!control_reader_); |
return bootstrap_->Connect(); |
} |
void ChannelMojo::Close() { |
- control_reader_.reset(); |
message_reader_.reset(); |
channel_info_.reset(); |
} |
-void ChannelMojo::OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) { |
- InitControlReader(handle.Pass()); |
- control_reader_->Connect(); |
-} |
- |
void ChannelMojo::OnBootstrapError() { |
listener_->OnChannelError(); |
} |
-void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { |
+void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe, |
+ int32_t peer_pid) { |
message_reader_ = |
make_scoped_ptr(new internal::MessageReader(pipe.Pass(), this)); |
@@ -175,6 +274,7 @@ void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { |
pending_messages_.clear(); |
+ set_peer_pid(peer_pid); |
listener_->OnChannelConnected(GetPeerPID()); |
} |