| Index: mojo/edk/system/channel_posix.cc
|
| diff --git a/mojo/edk/system/channel_posix.cc b/mojo/edk/system/channel_posix.cc
|
| index a7cf9e3df6cc83645cabcda729bdc1c23e78e471..7e9d171dd81233397f3276bfa02d0e341f0e28a1 100644
|
| --- a/mojo/edk/system/channel_posix.cc
|
| +++ b/mojo/edk/system/channel_posix.cc
|
| @@ -26,6 +26,11 @@
|
| #include <sys/uio.h>
|
| #endif
|
|
|
| +#if defined(OS_ANDROID)
|
| +#include "base/android/parcelable_channel_client.h"
|
| +#include "base/android/scoped_java_ref.h"
|
| +#endif
|
| +
|
| namespace mojo {
|
| namespace edk {
|
|
|
| @@ -39,10 +44,13 @@ class MessageView {
|
| public:
|
| // Owns |message|. |offset| indexes the first unsent byte in the message.
|
| MessageView(Channel::MessagePtr message, size_t offset)
|
| - : message_(std::move(message)),
|
| - offset_(offset),
|
| - handles_(message_->TakeHandlesForTransport()) {
|
| + : message_(std::move(message)), offset_(offset) {
|
| DCHECK_GT(message_->data_num_bytes(), offset_);
|
| +#if defined(OS_ANDROID)
|
| + // Parcelables must be retrieved before Handles.
|
| + ids_and_parcelables_ = message_->TakeParcelablesForTransport();
|
| +#endif
|
| + handles_ = message_->TakeHandlesForTransport();
|
| }
|
|
|
| MessageView(MessageView&& other) { *this = std::move(other); }
|
| @@ -70,6 +78,12 @@ class MessageView {
|
|
|
| ScopedPlatformHandleVectorPtr TakeHandles() { return std::move(handles_); }
|
| Channel::MessagePtr TakeMessage() { return std::move(message_); }
|
| +#if defined(OS_ANDROID)
|
| + Channel::Message::IDAndParcelableVector TakeParcelables() {
|
| + return std::move(ids_and_parcelables_);
|
| + }
|
| +
|
| +#endif
|
|
|
| void SetHandles(ScopedPlatformHandleVectorPtr handles) {
|
| handles_ = std::move(handles);
|
| @@ -79,6 +93,9 @@ class MessageView {
|
| Channel::MessagePtr message_;
|
| size_t offset_;
|
| ScopedPlatformHandleVectorPtr handles_;
|
| +#if defined(OS_ANDROID)
|
| + Channel::Message::IDAndParcelableVector ids_and_parcelables_;
|
| +#endif
|
|
|
| DISALLOW_COPY_AND_ASSIGN(MessageView);
|
| };
|
| @@ -88,17 +105,28 @@ class ChannelPosix : public Channel,
|
| public base::MessageLoopForIO::Watcher {
|
| public:
|
| ChannelPosix(Delegate* delegate,
|
| - ScopedPlatformHandle handle,
|
| + ConnectionParam connection_param,
|
| scoped_refptr<base::TaskRunner> io_task_runner)
|
| : Channel(delegate),
|
| self_(this),
|
| - handle_(std::move(handle)),
|
| + handle_(connection_param.TakeChannelHandle()),
|
| +#if defined(OS_ANDROID)
|
| + parcelable_channel_client_(
|
| + connection_param.TakeParcelableChannelClient()),
|
| + parcelable_channel_server_(
|
| + connection_param.TakeParcelableChannelServer()),
|
| +#endif
|
| io_task_runner_(io_task_runner)
|
| #if defined(OS_MACOSX)
|
| ,
|
| handles_to_close_(new PlatformHandleVector)
|
| #endif
|
| {
|
| + CHECK(handle_.is_valid());
|
| + // We can't DCHECK because the BrokerHost has a channel used for sync
|
| + // messages with not parcelable channels.
|
| + // CHECK(parcelable_channel_client_.is_valid());
|
| + // CHECK(parcelable_channel_server_.is_valid());
|
| }
|
|
|
| void Start() override {
|
| @@ -149,6 +177,7 @@ class ChannelPosix : public Channel,
|
| ScopedPlatformHandleVectorPtr* handles) override {
|
| if (num_handles > std::numeric_limits<uint16_t>::max())
|
| return false;
|
| +
|
| #if defined(OS_MACOSX) && !defined(OS_IOS)
|
| // On OSX, we can have mach ports which are located in the extra header
|
| // section.
|
| @@ -183,6 +212,35 @@ class ChannelPosix : public Channel,
|
| incoming_platform_handles_.pop_front();
|
| }
|
| }
|
| +#elif defined(OS_ANDROID)
|
| + using ParcelableEntry = Channel::Message::ParcelableEntry;
|
| + using ParcelableExtraHeader = Channel::Message::ParcelableExtraHeader;
|
| + CHECK(extra_header_size >= sizeof(ParcelableExtraHeader) +
|
| + num_handles * sizeof(ParcelableEntry));
|
| + const ParcelableExtraHeader* parcelable_header =
|
| + reinterpret_cast<const ParcelableExtraHeader*>(extra_header);
|
| + size_t num_parcelables = parcelable_header->num_parcelables;
|
| + CHECK(num_parcelables <= num_handles);
|
| + if (incoming_platform_handles_.size() + num_parcelables < num_handles) {
|
| + handles->reset();
|
| + return true;
|
| + }
|
| +
|
| + handles->reset(new PlatformHandleVector(num_handles));
|
| + const ParcelableEntry* parcelables = parcelable_header->entries;
|
| + for (size_t i = 0, parcelable_index = 0; i < num_handles; ++i) {
|
| + if (parcelable_index < num_parcelables &&
|
| + parcelables[parcelable_index].index == i) {
|
| + (*handles)->at(i) =
|
| + PlatformHandle(parcelable_channel_server_.TakeParcelable(
|
| + parcelables[parcelable_index].id));
|
| + parcelable_index++;
|
| + } else {
|
| + CHECK(!incoming_platform_handles_.empty());
|
| + (*handles)->at(i) = incoming_platform_handles_.front();
|
| + incoming_platform_handles_.pop_front();
|
| + }
|
| + }
|
| #else
|
| if (incoming_platform_handles_.size() < num_handles) {
|
| handles->reset();
|
| @@ -358,6 +416,17 @@ class ChannelPosix : public Channel,
|
| message_view.advance_data_offset(bytes_written);
|
|
|
| ssize_t result;
|
| +#if defined(OS_ANDROID)
|
| + Channel::Message::IDAndParcelableVector ids_and_parcelables =
|
| + std::move(message_view.TakeParcelables());
|
| + if (!ids_and_parcelables.empty()) {
|
| + for (auto iter = ids_and_parcelables.begin();
|
| + iter != ids_and_parcelables.end(); ++iter) {
|
| + DCHECK(!iter->second.is_null());
|
| + parcelable_channel_client_.SendParcelable(iter->first, iter->second);
|
| + }
|
| + }
|
| +#endif
|
| ScopedPlatformHandleVectorPtr handles = message_view.TakeHandles();
|
| if (handles && handles->size()) {
|
| iovec iov = {
|
| @@ -532,6 +601,10 @@ class ChannelPosix : public Channel,
|
| scoped_refptr<Channel> self_;
|
|
|
| ScopedPlatformHandle handle_;
|
| +#if defined(OS_ANDROID)
|
| + base::android::ParcelableChannelClient parcelable_channel_client_;
|
| + base::android::ParcelableChannelServer parcelable_channel_server_;
|
| +#endif
|
| scoped_refptr<base::TaskRunner> io_task_runner_;
|
|
|
| // These watchers must only be accessed on the IO thread.
|
| @@ -561,9 +634,10 @@ class ChannelPosix : public Channel,
|
| // static
|
| scoped_refptr<Channel> Channel::Create(
|
| Delegate* delegate,
|
| - ScopedPlatformHandle platform_handle,
|
| + ConnectionParam connection_param,
|
| scoped_refptr<base::TaskRunner> io_task_runner) {
|
| - return new ChannelPosix(delegate, std::move(platform_handle), io_task_runner);
|
| + return new ChannelPosix(delegate, std::move(connection_param),
|
| + io_task_runner);
|
| }
|
|
|
| } // namespace edk
|
|
|