diff options
author | morrita <morrita@chromium.org> | 2014-10-27 13:10:25 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-27 20:10:38 +0000 |
commit | f8f92dcd264f565033fef993d2f9e9b0cabd3d40 (patch) | |
tree | aacad78a60e74fdc994f439a64b3a1300059b89e /ipc | |
parent | b1dfa83e1c9e953b6e0115d27946bf186cc26619 (diff) | |
download | chromium_src-f8f92dcd264f565033fef993d2f9e9b0cabd3d40.zip chromium_src-f8f92dcd264f565033fef993d2f9e9b0cabd3d40.tar.gz chromium_src-f8f92dcd264f565033fef993d2f9e9b0cabd3d40.tar.bz2 |
ChannelMojo: Replace hand written messsages with mojo.
This change introduces client_channel.mojom to define
internal messages for ChannelMojo. Hand-written HelloMessage
routines are no longer needed.
This is a preparation for coming fix which needs additional
internal messages.
TEST=ipc_mojo_unittest
R=viettrungluu@chromium.org
BUG=377980
Review URL: https://codereview.chromium.org/679453002
Cr-Commit-Position: refs/heads/master@{#301428}
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/mojo/BUILD.gn | 10 | ||||
-rw-r--r-- | ipc/mojo/client_channel.mojom | 11 | ||||
-rw-r--r-- | ipc/mojo/ipc_channel_mojo.cc | 168 | ||||
-rw-r--r-- | ipc/mojo/ipc_channel_mojo.h | 12 | ||||
-rw-r--r-- | ipc/mojo/ipc_channel_mojo_readers.cc | 237 | ||||
-rw-r--r-- | ipc/mojo/ipc_mojo.gyp | 2 |
6 files changed, 170 insertions, 270 deletions
diff --git a/ipc/mojo/BUILD.gn b/ipc/mojo/BUILD.gn index 29905bd..324cc9a 100644 --- a/ipc/mojo/BUILD.gn +++ b/ipc/mojo/BUILD.gn @@ -2,8 +2,17 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//mojo/public/tools/bindings/mojom.gni") + +mojom("client_channel") { + sources = [ + "client_channel.mojom", + ] +} + component("mojo") { sources = [ + "client_channel.mojom", "ipc_channel_mojo.cc", "ipc_channel_mojo.h", "ipc_channel_mojo_host.cc", @@ -25,6 +34,7 @@ component("mojo") { "//mojo/environment:chromium", "//mojo/public/cpp/bindings", "//mojo/edk/system", + ":client_channel", ] } diff --git a/ipc/mojo/client_channel.mojom b/ipc/mojo/client_channel.mojom new file mode 100644 index 0000000..b2da0d4 --- /dev/null +++ b/ipc/mojo/client_channel.mojom @@ -0,0 +1,11 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module IPC { + +interface ClientChannel { + Init(handle<message_pipe> pipe, int32 peer_pid) => (int32 pid); +}; + +} diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc index bd3ceb5..4051bb5 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,125 @@ 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); + ~ClientChannelMojo() override; + // MojoBootstrap::Delegate implementation + void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; + // InterfaceImpl implementation + void OnConnectionError() override; + // ClientChannel implementation + void Init( + mojo::ScopedMessagePipeHandle pipe, + int32_t peer_pid, + const mojo::Callback<void(int32_t)>& callback) override; + + DISALLOW_COPY_AND_ASSIGN(ClientChannelMojo); +}; + +ClientChannelMojo::ClientChannelMojo(ChannelMojo::Delegate* delegate, + const ChannelHandle& handle, + Listener* listener) + : ChannelMojo(delegate, handle, Channel::MODE_CLIENT, listener) { +} + +ClientChannelMojo::~ClientChannelMojo() { +} + +void ClientChannelMojo::OnPipeAvailable( + mojo::embedder::ScopedPlatformHandle handle) { + mojo::WeakBindToPipe(this, CreateMessagingPipe(handle.Pass())); +} + +void ClientChannelMojo::OnConnectionError() { + listener()->OnChannelError(); +} + +void ClientChannelMojo::Init( + mojo::ScopedMessagePipeHandle pipe, + int32_t peer_pid, + const mojo::Callback<void(int32_t)>& callback) { + InitMessageReader(pipe.Pass(), static_cast<base::ProcessId>(peer_pid)); + callback.Run(GetSelfPID()); +} + +//------------------------------------------------------------------------------ + +class ServerChannelMojo : public ChannelMojo, public mojo::ErrorHandler { + public: + ServerChannelMojo(ChannelMojo::Delegate* delegate, + const ChannelHandle& handle, + Listener* listener); + ~ServerChannelMojo() override; + + // MojoBootstrap::Delegate implementation + void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; + // ErrorHandler implementation + void OnConnectionError() override; + // Channel override + void Close() override; + + private: + // ClientChannelClient implementation + void ClientChannelWasInitialized(int32_t peer_pid); + + mojo::InterfacePtr<ClientChannel> client_channel_; + mojo::ScopedMessagePipeHandle message_pipe_; + + DISALLOW_COPY_AND_ASSIGN(ServerChannelMojo); +}; + +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(nullptr, &message_pipe_, &peer); + if (create_result != MOJO_RESULT_OK) { + DLOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result; + listener()->OnChannelError(); + return; + } + + client_channel_.Bind(CreateMessagingPipe(handle.Pass())); + client_channel_.set_error_handler(this); + client_channel_->Init( + peer.Pass(), + static_cast<int32_t>(GetSelfPID()), + base::Bind(&ServerChannelMojo::ClientChannelWasInitialized, + base::Unretained(this))); +} + +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 +184,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 +245,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,7 +286,8 @@ void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { pending_messages_.clear(); - listener_->OnChannelConnected(GetPeerPID()); + set_peer_pid(peer_pid); + listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID())); } void ChannelMojo::OnPipeClosed(internal::MessagePipeReader* reader) { diff --git a/ipc/mojo/ipc_channel_mojo.h b/ipc/mojo/ipc_channel_mojo.h index e5a4e33..45d2482 100644 --- a/ipc/mojo/ipc_channel_mojo.h +++ b/ipc/mojo/ipc_channel_mojo.h @@ -114,15 +114,12 @@ class IPC_MOJO_EXPORT ChannelMojo : public Channel, #endif // defined(OS_POSIX) && !defined(OS_NACL) // MojoBootstrapDelegate implementation - void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; void OnBootstrapError() override; // Called from MessagePipeReader implementations void OnMessageReceived(Message& message); - void OnConnected(mojo::ScopedMessagePipeHandle pipe); void OnPipeClosed(internal::MessagePipeReader* reader); void OnPipeError(internal::MessagePipeReader* reader); - void set_peer_pid(base::ProcessId pid) { peer_pid_ = pid; } protected: ChannelMojo(Delegate* delegate, @@ -130,6 +127,13 @@ class IPC_MOJO_EXPORT ChannelMojo : public Channel, Mode mode, Listener* listener); + mojo::ScopedMessagePipeHandle CreateMessagingPipe( + mojo::embedder::ScopedPlatformHandle handle); + void InitMessageReader(mojo::ScopedMessagePipeHandle pipe, int32_t peer_pid); + + Listener* listener() const { return listener_; } + void set_peer_pid(base::ProcessId pid) { peer_pid_ = pid; } + private: struct ChannelInfoDeleter { void operator()(mojo::embedder::ChannelInfo* ptr) const; @@ -141,7 +145,6 @@ class IPC_MOJO_EXPORT ChannelMojo : public Channel, typedef internal::MessagePipeReader::DelayedDeleter ReaderDeleter; void InitDelegate(ChannelMojo::Delegate* delegate); - void InitControlReader(mojo::embedder::ScopedPlatformHandle handle); scoped_ptr<MojoBootstrap> bootstrap_; base::WeakPtr<Delegate> delegate_; @@ -151,7 +154,6 @@ class IPC_MOJO_EXPORT ChannelMojo : public Channel, scoped_ptr<mojo::embedder::ChannelInfo, ChannelInfoDeleter> channel_info_; - scoped_ptr<internal::ControlReader, ReaderDeleter> control_reader_; scoped_ptr<internal::MessageReader, ReaderDeleter> message_reader_; ScopedVector<Message> pending_messages_; diff --git a/ipc/mojo/ipc_channel_mojo_readers.cc b/ipc/mojo/ipc_channel_mojo_readers.cc index 2c231bf..e4a35c5 100644 --- a/ipc/mojo/ipc_channel_mojo_readers.cc +++ b/ipc/mojo/ipc_channel_mojo_readers.cc @@ -5,91 +5,10 @@ #include "ipc/mojo/ipc_channel_mojo_readers.h" #include "ipc/mojo/ipc_channel_mojo.h" -#include "mojo/edk/embedder/embedder.h" - -#if defined(OS_POSIX) && !defined(OS_NACL) -#include "ipc/file_descriptor_set_posix.h" -#endif namespace IPC { namespace internal { -namespace { - -// TODO(morrita): This should be built using higher-level Mojo construct -// for clarity and extensibility. -class HelloMessage { - public: - static Pickle CreateRequest(int32 pid) { - Pickle request; - request.WriteString(kHelloRequestMagic); - request.WriteInt(pid); - return request; - } - - static bool ReadRequest(Pickle& pickle, int32* pid) { - PickleIterator iter(pickle); - std::string hello; - if (!iter.ReadString(&hello)) { - DLOG(WARNING) << "Failed to Read magic string."; - return false; - } - - if (hello != kHelloRequestMagic) { - DLOG(WARNING) << "Magic mismatch:" << hello; - return false; - } - - int read_pid; - if (!iter.ReadInt(&read_pid)) { - DLOG(WARNING) << "Failed to Read PID."; - return false; - } - - *pid = read_pid; - return true; - } - - static Pickle CreateResponse(int32 pid) { - Pickle request; - request.WriteString(kHelloResponseMagic); - request.WriteInt(pid); - return request; - } - - static bool ReadResponse(Pickle& pickle, int32* pid) { - PickleIterator iter(pickle); - std::string hello; - if (!iter.ReadString(&hello)) { - DLOG(WARNING) << "Failed to read magic string."; - return false; - } - - if (hello != kHelloResponseMagic) { - DLOG(WARNING) << "Magic mismatch:" << hello; - return false; - } - - int read_pid; - if (!iter.ReadInt(&read_pid)) { - DLOG(WARNING) << "Failed to read PID."; - return false; - } - - *pid = read_pid; - return true; - } - - private: - static const char* kHelloRequestMagic; - static const char* kHelloResponseMagic; -}; - -const char* HelloMessage::kHelloRequestMagic = "MREQ"; -const char* HelloMessage::kHelloResponseMagic = "MRES"; - -} // namespace - //------------------------------------------------------------------------------ MessageReader::MessageReader(mojo::ScopedMessagePipeHandle pipe, @@ -161,161 +80,5 @@ bool MessageReader::Send(scoped_ptr<Message> message) { return true; } -//------------------------------------------------------------------------------ - -ControlReader::ControlReader(mojo::ScopedMessagePipeHandle pipe, - ChannelMojo* owner) - : internal::MessagePipeReader(pipe.Pass()), owner_(owner) { -} - -void ControlReader::OnPipeClosed() { - if (!owner_) - return; - owner_->OnPipeClosed(this); - owner_ = NULL; -} - -void ControlReader::OnPipeError(MojoResult error) { - if (!owner_) - return; - owner_->OnPipeError(this); -} - -bool ControlReader::Connect() { - return true; -} - -//------------------------------------------------------------------------------ - -ServerControlReader::ServerControlReader(mojo::ScopedMessagePipeHandle pipe, - ChannelMojo* owner) - : ControlReader(pipe.Pass(), owner) { -} - -ServerControlReader::~ServerControlReader() { -} - -bool ServerControlReader::Connect() { - MojoResult result = SendHelloRequest(); - if (result != MOJO_RESULT_OK) { - CloseWithError(result); - return false; - } - - return true; -} - -MojoResult ServerControlReader::SendHelloRequest() { - DCHECK(IsValid()); - DCHECK(!message_pipe_.is_valid()); - - mojo::ScopedMessagePipeHandle self; - mojo::ScopedMessagePipeHandle peer; - MojoResult create_result = - mojo::CreateMessagePipe(NULL, &message_pipe_, &peer); - if (MOJO_RESULT_OK != create_result) { - DLOG(WARNING) << "mojo::CreateMessagePipe failed: " << create_result; - return create_result; - } - - MojoHandle peer_to_send = peer.get().value(); - Pickle request = HelloMessage::CreateRequest(owner_->GetSelfPID()); - MojoResult write_result = - MojoWriteMessage(handle(), - request.data(), - static_cast<uint32>(request.size()), - &peer_to_send, - 1, - MOJO_WRITE_MESSAGE_FLAG_NONE); - if (MOJO_RESULT_OK != write_result) { - DLOG(WARNING) << "Writing Hello request failed: " << create_result; - return write_result; - } - - // |peer| is sent and no longer owned by |this|. - (void)peer.release(); - return MOJO_RESULT_OK; -} - -MojoResult ServerControlReader::RespondHelloResponse() { - Pickle request(data_buffer().empty() ? "" : &data_buffer()[0], - static_cast<uint32>(data_buffer().size())); - - int32 read_pid = 0; - if (!HelloMessage::ReadResponse(request, &read_pid)) { - DLOG(ERROR) << "Failed to parse Hello response."; - return MOJO_RESULT_UNKNOWN; - } - - base::ProcessId pid = static_cast<base::ProcessId>(read_pid); - owner_->set_peer_pid(pid); - owner_->OnConnected(message_pipe_.Pass()); - return MOJO_RESULT_OK; -} - -void ServerControlReader::OnMessageReceived() { - MojoResult result = RespondHelloResponse(); - if (result != MOJO_RESULT_OK) - CloseWithError(result); -} - -//------------------------------------------------------------------------------ - -ClientControlReader::ClientControlReader(mojo::ScopedMessagePipeHandle pipe, - ChannelMojo* owner) - : ControlReader(pipe.Pass(), owner) { -} - -MojoResult ClientControlReader::RespondHelloRequest( - MojoHandle message_channel) { - DCHECK(IsValid()); - - mojo::ScopedMessagePipeHandle received_pipe( - (mojo::MessagePipeHandle(message_channel))); - - int32 read_request = 0; - Pickle request(data_buffer().empty() ? "" : &data_buffer()[0], - static_cast<uint32>(data_buffer().size())); - if (!HelloMessage::ReadRequest(request, &read_request)) { - DLOG(ERROR) << "Hello request has wrong magic."; - return MOJO_RESULT_UNKNOWN; - } - - base::ProcessId pid = read_request; - Pickle response = HelloMessage::CreateResponse(owner_->GetSelfPID()); - MojoResult write_result = - MojoWriteMessage(handle(), - response.data(), - static_cast<uint32>(response.size()), - NULL, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE); - if (MOJO_RESULT_OK != write_result) { - DLOG(ERROR) << "Writing Hello response failed: " << write_result; - return write_result; - } - - owner_->set_peer_pid(pid); - owner_->OnConnected(received_pipe.Pass()); - return MOJO_RESULT_OK; -} - -void ClientControlReader::OnMessageReceived() { - std::vector<MojoHandle> handle_buffer; - TakeHandleBuffer(&handle_buffer); - if (handle_buffer.size() != 1) { - DLOG(ERROR) << "Hello request doesn't contains required handle: " - << handle_buffer.size(); - CloseWithError(MOJO_RESULT_UNKNOWN); - return; - } - - MojoResult result = RespondHelloRequest(handle_buffer[0]); - if (result != MOJO_RESULT_OK) { - DLOG(ERROR) << "Failed to respond Hello request. Closing: " << result; - CloseWithError(result); - } -} - } // namespace internal } // namespace IPC diff --git a/ipc/mojo/ipc_mojo.gyp b/ipc/mojo/ipc_mojo.gyp index 1dde7ee..a9a2673 100644 --- a/ipc/mojo/ipc_mojo.gyp +++ b/ipc/mojo/ipc_mojo.gyp @@ -17,6 +17,7 @@ 'defines': [ 'IPC_MOJO_IMPLEMENTATION', ], + 'includes': [ '../../mojo/public/tools/bindings/mojom_bindings_generator.gypi' ], 'dependencies': [ '../ipc.gyp:ipc', '../../base/base.gyp:base', @@ -26,6 +27,7 @@ '../../mojo/public/mojo_public.gyp:mojo_cpp_bindings', ], 'sources': [ + 'client_channel.mojom', 'ipc_channel_mojo.cc', 'ipc_channel_mojo.h', 'ipc_channel_mojo_host.cc', |