blob: 80c42fd6d47b35a97c1b34dc3630bb423f0cea7f [file] [log] [blame]
// Copyright (c) 2011 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.
#include "content/child/webmessageportchannel_impl.h"
#include <stddef.h>
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "third_party/WebKit/public/platform/WebMessagePortChannel.h"
#include "third_party/WebKit/public/platform/WebMessagePortChannelClient.h"
#include "third_party/WebKit/public/platform/WebString.h"
using blink::WebMessagePortChannel;
using blink::WebMessagePortChannelArray;
using blink::WebMessagePortChannelClient;
using blink::WebString;
namespace content {
WebMessagePortChannelImpl::~WebMessagePortChannelImpl() {
SetClient(nullptr);
}
WebMessagePortChannelImpl::WebMessagePortChannelImpl(
MessagePort message_port)
: port_(message_port.ReleaseHandle()) {
}
// static
void WebMessagePortChannelImpl::CreatePair(
std::unique_ptr<blink::WebMessagePortChannel>* channel1,
std::unique_ptr<blink::WebMessagePortChannel>* channel2) {
mojo::MessagePipe pipe;
// Constructor is private, so use WrapUnique here.
*channel1 =
base::WrapUnique(new WebMessagePortChannelImpl(std::move(pipe.handle0)));
*channel2 =
base::WrapUnique(new WebMessagePortChannelImpl(std::move(pipe.handle1)));
}
// static
std::vector<MessagePort>
WebMessagePortChannelImpl::ExtractMessagePorts(
WebMessagePortChannelArray channels) {
std::vector<MessagePort> message_ports(channels.size());
for (size_t i = 0; i < channels.size(); ++i) {
WebMessagePortChannelImpl* channel_impl =
static_cast<WebMessagePortChannelImpl*>(channels[i].get());
message_ports[i] = channel_impl->ReleaseMessagePort();
DCHECK(message_ports[i].GetHandle().is_valid());
}
return message_ports;
}
// static
WebMessagePortChannelArray
WebMessagePortChannelImpl::CreateFromMessagePorts(
const std::vector<MessagePort>& message_ports) {
WebMessagePortChannelArray channels(message_ports.size());
for (size_t i = 0; i < message_ports.size(); ++i)
channels[i] = base::MakeUnique<WebMessagePortChannelImpl>(message_ports[i]);
return channels;
}
// static
WebMessagePortChannelArray
WebMessagePortChannelImpl::CreateFromMessagePipeHandles(
std::vector<mojo::ScopedMessagePipeHandle> handles) {
WebMessagePortChannelArray channels(handles.size());
for (size_t i = 0; i < handles.size(); ++i) {
channels[i] = base::MakeUnique<WebMessagePortChannelImpl>(
MessagePort(std::move(handles[i])));
}
return channels;
}
MessagePort WebMessagePortChannelImpl::ReleaseMessagePort() {
return MessagePort(port_.ReleaseHandle());
}
WebMessagePortChannelImpl::WebMessagePortChannelImpl(
mojo::ScopedMessagePipeHandle handle)
: port_(std::move(handle)) {
}
void WebMessagePortChannelImpl::SetClient(WebMessagePortChannelClient* client) {
if (client) {
port_.SetCallback(base::Bind(&WebMessagePortChannelClient::MessageAvailable,
base::Unretained(client)));
} else {
port_.ClearCallback();
}
}
void WebMessagePortChannelImpl::PostMessage(
const uint8_t* encoded_message,
size_t encoded_message_size,
WebMessagePortChannelArray channels) {
std::vector<MessagePort> ports;
if (!channels.IsEmpty()) {
ports.resize(channels.size());
for (size_t i = 0; i < channels.size(); ++i) {
ports[i] = static_cast<WebMessagePortChannelImpl*>(channels[i].get())->
ReleaseMessagePort();
}
}
port_.PostMessage(encoded_message, encoded_message_size, std::move(ports));
}
bool WebMessagePortChannelImpl::TryGetMessage(
blink::WebVector<uint8_t>* encoded_message,
WebMessagePortChannelArray& channels) {
std::vector<uint8_t> buffer;
std::vector<MessagePort> ports;
if (!port_.GetMessage(&buffer, &ports))
return false;
*encoded_message = std::move(buffer);
if (!ports.empty()) {
channels = WebMessagePortChannelArray(ports.size());
for (size_t i = 0; i < ports.size(); ++i)
channels[i] = base::MakeUnique<WebMessagePortChannelImpl>(ports[i]);
}
return true;
}
} // namespace content