PlatformMessagePortChannel.cpp [plain text]
#include "config.h"
#include "PlatformMessagePortChannel.h"
#include "MessagePort.h"
#include "ScriptExecutionContext.h"
#include "SerializedScriptValue.h"
#include "WebKit.h"
#include "platform/WebKitPlatformSupport.h"
#include "WebMessagePortChannel.h"
#include "platform/WebString.h"
using namespace WebKit;
namespace WebCore {
PassOwnPtr<MessagePortChannel> MessagePortChannel::create(PassRefPtr<PlatformMessagePortChannel> channel)
{
return adoptPtr(new MessagePortChannel(channel));
}
void MessagePortChannel::createChannel(PassRefPtr<MessagePort> port1, PassRefPtr<MessagePort> port2)
{
PlatformMessagePortChannel::createChannel(port1, port2);
}
MessagePortChannel::MessagePortChannel(PassRefPtr<PlatformMessagePortChannel> channel)
: m_channel(channel)
{
}
MessagePortChannel::~MessagePortChannel()
{
m_channel->close();
}
bool MessagePortChannel::entangleIfOpen(MessagePort* port)
{
return m_channel->entangleIfOpen(port);
}
void MessagePortChannel::disentangle()
{
m_channel->disentangle();
}
void MessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message)
{
m_channel->postMessageToRemote(message);
}
bool MessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result)
{
return m_channel->tryGetMessageFromRemote(result);
}
void MessagePortChannel::close()
{
m_channel->close();
}
bool MessagePortChannel::isConnectedTo(MessagePort* port)
{
return m_channel->isConnectedTo(port);
}
bool MessagePortChannel::hasPendingActivity()
{
return m_channel->hasPendingActivity();
}
MessagePort* MessagePortChannel::locallyEntangledPort(const ScriptExecutionContext* context)
{
return 0;
}
PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::create()
{
return adoptRef(new PlatformMessagePortChannel());
}
PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::create(
WebMessagePortChannel* channel)
{
return adoptRef(new PlatformMessagePortChannel(channel));
}
PlatformMessagePortChannel::PlatformMessagePortChannel()
: m_localPort(0)
{
m_webChannel = webKitPlatformSupport()->createMessagePortChannel();
if (m_webChannel)
m_webChannel->setClient(this);
}
PlatformMessagePortChannel::PlatformMessagePortChannel(WebMessagePortChannel* channel)
: m_localPort(0)
, m_webChannel(channel)
{
}
PlatformMessagePortChannel::~PlatformMessagePortChannel()
{
if (m_webChannel)
m_webChannel->destroy();
}
void PlatformMessagePortChannel::createChannel(PassRefPtr<MessagePort> port1, PassRefPtr<MessagePort> port2)
{
RefPtr<PlatformMessagePortChannel> channel1 = PlatformMessagePortChannel::create();
RefPtr<PlatformMessagePortChannel> channel2 = PlatformMessagePortChannel::create();
channel1->setEntangledChannel(channel2);
channel2->setEntangledChannel(channel1);
port1->entangle(MessagePortChannel::create(channel2));
port2->entangle(MessagePortChannel::create(channel1));
}
void PlatformMessagePortChannel::messageAvailable()
{
MutexLocker lock(m_mutex);
if (m_localPort)
m_localPort->messageAvailable();
}
bool PlatformMessagePortChannel::entangleIfOpen(MessagePort* port)
{
MutexLocker lock(m_mutex);
m_localPort = port;
return true;
}
void PlatformMessagePortChannel::disentangle()
{
MutexLocker lock(m_mutex);
m_localPort = 0;
}
void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message)
{
if (!m_localPort || !m_webChannel)
return;
WebString messageString = message->message()->toWireString();
OwnPtr<WebCore::MessagePortChannelArray> channels = message->channels();
WebMessagePortChannelArray* webChannels = 0;
if (channels && channels->size()) {
webChannels = new WebMessagePortChannelArray(channels->size());
for (size_t i = 0; i < channels->size(); ++i) {
WebCore::PlatformMessagePortChannel* platformChannel = (*channels)[i]->channel();
(*webChannels)[i] = platformChannel->webChannelRelease();
(*webChannels)[i]->setClient(0);
}
}
m_webChannel->postMessage(messageString, webChannels);
}
bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result)
{
if (!m_webChannel)
return false;
WebString message;
WebMessagePortChannelArray webChannels;
bool rv = m_webChannel->tryGetMessage(&message, webChannels);
if (rv) {
OwnPtr<MessagePortChannelArray> channels;
if (webChannels.size()) {
channels = adoptPtr(new MessagePortChannelArray(webChannels.size()));
for (size_t i = 0; i < webChannels.size(); ++i) {
RefPtr<PlatformMessagePortChannel> platformChannel = create(webChannels[i]);
webChannels[i]->setClient(platformChannel.get());
(*channels)[i] = MessagePortChannel::create(platformChannel);
}
}
RefPtr<SerializedScriptValue> serializedMessage = SerializedScriptValue::createFromWire(message);
result = MessagePortChannel::EventData::create(serializedMessage.release(), channels.release());
}
return rv;
}
void PlatformMessagePortChannel::close()
{
MutexLocker lock(m_mutex);
m_localPort = 0;
m_entangledChannel = 0;
}
bool PlatformMessagePortChannel::isConnectedTo(MessagePort* port)
{
MutexLocker lock(m_mutex);
return m_entangledChannel && m_entangledChannel->m_localPort == port;
}
bool PlatformMessagePortChannel::hasPendingActivity()
{
MutexLocker lock(m_mutex);
return m_localPort;
}
void PlatformMessagePortChannel::setEntangledChannel(PassRefPtr<PlatformMessagePortChannel> remote)
{
if (m_webChannel)
m_webChannel->entangle(remote->m_webChannel);
MutexLocker lock(m_mutex);
m_entangledChannel = remote;
}
WebMessagePortChannel* PlatformMessagePortChannel::webChannelRelease()
{
WebMessagePortChannel* rv = m_webChannel;
m_webChannel = 0;
return rv;
}
}