summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authormorrita <morrita@chromium.org>2014-10-27 13:10:25 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-27 20:10:38 +0000
commitf8f92dcd264f565033fef993d2f9e9b0cabd3d40 (patch)
treeaacad78a60e74fdc994f439a64b3a1300059b89e /ipc
parentb1dfa83e1c9e953b6e0115d27946bf186cc26619 (diff)
downloadchromium_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.gn10
-rw-r--r--ipc/mojo/client_channel.mojom11
-rw-r--r--ipc/mojo/ipc_channel_mojo.cc168
-rw-r--r--ipc/mojo/ipc_channel_mojo.h12
-rw-r--r--ipc/mojo/ipc_channel_mojo_readers.cc237
-rw-r--r--ipc/mojo/ipc_mojo.gyp2
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',