diff options
Diffstat (limited to 'Source/WebKit/chromium/src/PlatformMessagePortChannel.cpp')
-rw-r--r-- | Source/WebKit/chromium/src/PlatformMessagePortChannel.cpp | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/Source/WebKit/chromium/src/PlatformMessagePortChannel.cpp b/Source/WebKit/chromium/src/PlatformMessagePortChannel.cpp new file mode 100644 index 0000000..aa42a10 --- /dev/null +++ b/Source/WebKit/chromium/src/PlatformMessagePortChannel.cpp @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PlatformMessagePortChannel.h" + +#include "MessagePort.h" +#include "ScriptExecutionContext.h" +#include "SerializedScriptValue.h" + +#include "WebKit.h" +#include "WebKitClient.h" +#include "WebMessagePortChannel.h" +#include "WebString.h" + +using namespace WebKit; + +namespace WebCore { + +PassOwnPtr<MessagePortChannel> MessagePortChannel::create(PassRefPtr<PlatformMessagePortChannel> channel) +{ + return 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() +{ + // Make sure we close our platform channel when the base is freed, to keep the channel objects from leaking. + 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) +{ + // This is just an optimization, so return 0 always. + 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 = webKitClient()->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) +{ + // Create proxies for each endpoint. + RefPtr<PlatformMessagePortChannel> channel1 = PlatformMessagePortChannel::create(); + RefPtr<PlatformMessagePortChannel> channel2 = PlatformMessagePortChannel::create(); + + // Entangle the two endpoints. + channel1->setEntangledChannel(channel2); + channel2->setEntangledChannel(channel1); + + // Now entangle the proxies with the appropriate local ports. + 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.get() && 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 = 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); + // Disentangle ourselves from the other end. We still maintain a reference to m_webChannel, + // since previously-existing messages should still be delivered. + 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; +} + +} // namespace WebCore |