Skip to content

Commit

Permalink
Adds associated interface support to IPC::Channel
Browse files Browse the repository at this point in the history
Provides a way of registering associated interface bindings with
an IPC::Channel endpoint and acquiring proxies to remote interfaces
on the other side.

Support for this is exposed by IPC::Channel but only implemented
in IPC::ChannelMojo.

This is part a series of CLs to support Channel-associated interfaces.

BUG=612500

Committed: https://crrev.com/dc88e5075878f16cde23b910d2ce19aa862129e4
Review-Url: https://codereview.chromium.org/2137353002
Cr-Original-Commit-Position: refs/heads/master@{#405316}
Cr-Commit-Position: refs/heads/master@{#405364}
  • Loading branch information
krockot authored and Commit bot committed Jul 14, 2016
1 parent 618f2d4 commit 7c6bf95
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 10 deletions.
8 changes: 8 additions & 0 deletions ipc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ mojom("mojom") {
]
}

mojom("test_interfaces") {
testonly = true
sources = [
"ipc_test.mojom",
]
}

# This is provided as a separate target so other targets can provide param
# traits implementations without necessarily linking to all of IPC.
source_set("param_traits") {
Expand Down Expand Up @@ -235,6 +242,7 @@ if (!is_ios) {
":ipc",
":mojom",
":run_all_unittests",
":test_interfaces",
":test_support",
"//base",
"//base:i18n",
Expand Down
9 changes: 9 additions & 0 deletions ipc/ipc.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@
'..',
],
},
{
'target_name': 'ipc_test_interfaces',
'type': 'static_library',
'sources': [
'ipc_test.mojom',
],
'includes': [ '../mojo/mojom_bindings_generator.gypi' ],
},
{
'target_name': 'ipc_run_all_unittests',
'type': 'static_library',
Expand All @@ -83,6 +91,7 @@
'dependencies': [
'ipc',
'ipc_run_all_unittests',
'ipc_test_interfaces',
'test_support_ipc',
'../base/base.gyp:base',
'../base/base.gyp:base_i18n',
Expand Down
6 changes: 6 additions & 0 deletions ipc/ipc.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ struct SerializedHandle {
Type type;
};

// A placeholder interface type since we don't yet support generic associated
// message pipe handles.
interface GenericInterface {};

interface Channel {
Receive(array<uint8> data, array<SerializedHandle>? handles);

GetAssociatedInterface(string name, associated GenericInterface& request);
};

// An interface for connecting a pair of Channel interfaces representing a
Expand Down
65 changes: 65 additions & 0 deletions ipc/ipc_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_endpoint.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"

#if defined(OS_POSIX)
#include <sys/types.h>
Expand Down Expand Up @@ -93,6 +97,62 @@ class IPC_EXPORT Channel : public Endpoint {
CLOSE_FD_MESSAGE_TYPE = HELLO_MESSAGE_TYPE - 1
};

// Helper interface a Channel may implement to expose support for associated
// Mojo interfaces.
class IPC_EXPORT AssociatedInterfaceSupport {
public:
using GenericAssociatedInterfaceFactory =
base::Callback<void(mojo::ScopedInterfaceEndpointHandle)>;

virtual ~AssociatedInterfaceSupport() {}

// Accesses the AssociatedGroup used to associate new interface endpoints
// with this Channel.
virtual mojo::AssociatedGroup* GetAssociatedGroup() = 0;

// Adds an interface factory to this channel for interface |name|.
virtual void AddGenericAssociatedInterface(
const std::string& name,
const GenericAssociatedInterfaceFactory& factory) = 0;

// Requests an associated interface from the remote endpoint.
virtual void GetGenericRemoteAssociatedInterface(
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) = 0;

// Template helper to add an interface factory to this channel.
template <typename Interface>
using AssociatedInterfaceFactory =
base::Callback<void(mojo::AssociatedInterfaceRequest<Interface>)>;
template <typename Interface>
void AddAssociatedInterface(
const AssociatedInterfaceFactory<Interface>& factory) {
AddGenericAssociatedInterface(
Interface::Name_,
base::Bind(&BindAssociatedInterfaceRequest<Interface>, factory));
}

// Template helper to request a remote associated interface.
template <typename Interface>
void GetRemoteAssociatedInterface(
mojo::AssociatedInterfacePtr<Interface>* proxy) {
mojo::AssociatedInterfaceRequest<Interface> request =
mojo::GetProxy(proxy, GetAssociatedGroup());
GetGenericRemoteAssociatedInterface(
Interface::Name_, request.PassHandle());
}

private:
template <typename Interface>
static void BindAssociatedInterfaceRequest(
const AssociatedInterfaceFactory<Interface>& factory,
mojo::ScopedInterfaceEndpointHandle handle) {
mojo::AssociatedInterfaceRequest<Interface> request;
request.Bind(std::move(handle));
factory.Run(std::move(request));
}
};

// The maximum message size in bytes. Attempting to receive a message of this
// size or bigger results in a channel error.
static const size_t kMaximumMessageSize = 128 * 1024 * 1024;
Expand Down Expand Up @@ -181,6 +241,11 @@ class IPC_EXPORT Channel : public Endpoint {
// Get its own process id. This value is told to the peer.
virtual base::ProcessId GetSelfPID() const = 0;

// Gets a helper for associating Mojo interfaces with this Channel.
//
// NOTE: Not all implementations support this.
virtual AssociatedInterfaceSupport* GetAssociatedInterfaceSupport();

// Overridden from ipc::Sender.
// Send a message over the Channel to the listener on the other end.
//
Expand Down
4 changes: 4 additions & 0 deletions ipc/ipc_channel_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ void Channel::GenerateMojoChannelHandlePair(
Channel::~Channel() {
}

Channel::AssociatedInterfaceSupport* Channel::GetAssociatedInterfaceSupport() {
return nullptr;
}

bool Channel::IsSendThreadSafe() const {
return false;
}
Expand Down
30 changes: 30 additions & 0 deletions ipc/ipc_channel_mojo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,14 @@ void ChannelMojo::OnBootstrapError() {
listener_->OnChannelError();
}

void ChannelMojo::OnAssociatedInterfaceRequest(
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) {
auto iter = associated_interfaces_.find(name);
if (iter != associated_interfaces_.end())
iter->second.Run(std::move(handle));
}

void ChannelMojo::InitMessageReader(mojom::ChannelAssociatedPtrInfo sender,
mojom::ChannelAssociatedRequest receiver,
base::ProcessId peer_pid) {
Expand Down Expand Up @@ -392,6 +400,9 @@ base::ProcessId ChannelMojo::GetSelfPID() const {
return bootstrap_->GetSelfPID();
}

Channel::AssociatedInterfaceSupport*
ChannelMojo::GetAssociatedInterfaceSupport() { return this; }

void ChannelMojo::OnMessageReceived(const Message& message) {
TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived",
"class", IPC_MESSAGE_ID_CLASS(message.type()),
Expand Down Expand Up @@ -468,4 +479,23 @@ MojoResult ChannelMojo::WriteToMessageAttachmentSet(
return MOJO_RESULT_OK;
}

mojo::AssociatedGroup* ChannelMojo::GetAssociatedGroup() {
DCHECK(bootstrap_);
return bootstrap_->GetAssociatedGroup();
}

void ChannelMojo::AddGenericAssociatedInterface(
const std::string& name,
const GenericAssociatedInterfaceFactory& factory) {
auto result = associated_interfaces_.insert({ name, factory });
DCHECK(result.second);
}

void ChannelMojo::GetGenericRemoteAssociatedInterface(
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) {
DCHECK(message_reader_);
message_reader_->GetRemoteInterface(name, std::move(handle));
}

} // namespace IPC
19 changes: 19 additions & 0 deletions ipc/ipc_channel_mojo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

#include <stdint.h>

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/macros.h"
Expand Down Expand Up @@ -37,6 +39,7 @@ namespace IPC {
//
class IPC_EXPORT ChannelMojo
: public Channel,
public Channel::AssociatedInterfaceSupport,
public MojoBootstrap::Delegate,
public NON_EXPORTED_BASE(internal::MessagePipeReader::Delegate) {
public:
Expand All @@ -62,6 +65,7 @@ class IPC_EXPORT ChannelMojo
bool IsSendThreadSafe() const override;
base::ProcessId GetPeerPID() const override;
base::ProcessId GetSelfPID() const override;
Channel::AssociatedInterfaceSupport* GetAssociatedInterfaceSupport() override;

#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
int GetClientFileDescriptor() const override;
Expand All @@ -82,6 +86,9 @@ class IPC_EXPORT ChannelMojo
mojom::ChannelAssociatedRequest receive_channel,
int32_t peer_pid) override;
void OnBootstrapError() override;
void OnAssociatedInterfaceRequest(
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) override;

// MessagePipeReader::Delegate
void OnMessageReceived(const Message& message) override;
Expand All @@ -96,6 +103,15 @@ class IPC_EXPORT ChannelMojo
mojom::ChannelAssociatedRequest receiver,
base::ProcessId peer_pid);

// Channel::AssociatedInterfaceSupport:
mojo::AssociatedGroup* GetAssociatedGroup() override;
void AddGenericAssociatedInterface(
const std::string& name,
const GenericAssociatedInterfaceFactory& factory) override;
void GetGenericRemoteAssociatedInterface(
const std::string& name,
mojo::ScopedInterfaceEndpointHandle handle) override;

// ChannelMojo needs to kill its MessagePipeReader in delayed manner
// because the channel wants to kill these readers during the
// notifications invoked by them.
Expand All @@ -108,6 +124,9 @@ class IPC_EXPORT ChannelMojo
std::unique_ptr<MojoBootstrap> bootstrap_;
Listener* listener_;

std::map<std::string, GenericAssociatedInterfaceFactory>
associated_interfaces_;

// Guards access to the fields below.
mutable base::Lock lock_;
std::unique_ptr<internal::MessagePipeReader, ReaderDeleter> message_reader_;
Expand Down
Loading

0 comments on commit 7c6bf95

Please sign in to comment.