WebKit/chromium/src/PlatformMessagePortChannel.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009 Google Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions are
       
     6  * met:
       
     7  *
       
     8  *     * Redistributions of source code must retain the above copyright
       
     9  * notice, this list of conditions and the following disclaimer.
       
    10  *     * Redistributions in binary form must reproduce the above
       
    11  * copyright notice, this list of conditions and the following disclaimer
       
    12  * in the documentation and/or other materials provided with the
       
    13  * distribution.
       
    14  *     * Neither the name of Google Inc. nor the names of its
       
    15  * contributors may be used to endorse or promote products derived from
       
    16  * this software without specific prior written permission.
       
    17  *
       
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    29  */
       
    30 
       
    31 #include "config.h"
       
    32 #include "PlatformMessagePortChannel.h"
       
    33 
       
    34 #include "MessagePort.h"
       
    35 #include "ScriptExecutionContext.h"
       
    36 #include "SerializedScriptValue.h"
       
    37 
       
    38 #include "WebKit.h"
       
    39 #include "WebKitClient.h"
       
    40 #include "WebMessagePortChannel.h"
       
    41 #include "WebString.h"
       
    42 
       
    43 using namespace WebKit;
       
    44 
       
    45 namespace WebCore {
       
    46 
       
    47 PassOwnPtr<MessagePortChannel> MessagePortChannel::create(PassRefPtr<PlatformMessagePortChannel> channel)
       
    48 {
       
    49     return new MessagePortChannel(channel);
       
    50 }
       
    51 
       
    52 void MessagePortChannel::createChannel(PassRefPtr<MessagePort> port1, PassRefPtr<MessagePort> port2)
       
    53 {
       
    54     PlatformMessagePortChannel::createChannel(port1, port2);
       
    55 }
       
    56 
       
    57 MessagePortChannel::MessagePortChannel(PassRefPtr<PlatformMessagePortChannel> channel)
       
    58     : m_channel(channel)
       
    59 {
       
    60 }
       
    61 
       
    62 MessagePortChannel::~MessagePortChannel()
       
    63 {
       
    64     // Make sure we close our platform channel when the base is freed, to keep the channel objects from leaking.
       
    65     m_channel->close();
       
    66 }
       
    67 
       
    68 bool MessagePortChannel::entangleIfOpen(MessagePort* port)
       
    69 {
       
    70     return m_channel->entangleIfOpen(port);
       
    71 }
       
    72 
       
    73 void MessagePortChannel::disentangle()
       
    74 {
       
    75     m_channel->disentangle();
       
    76 }
       
    77 
       
    78 void MessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message)
       
    79 {
       
    80     m_channel->postMessageToRemote(message);
       
    81 }
       
    82 
       
    83 bool MessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result)
       
    84 {
       
    85     return m_channel->tryGetMessageFromRemote(result);
       
    86 }
       
    87 
       
    88 void MessagePortChannel::close()
       
    89 {
       
    90     m_channel->close();
       
    91 }
       
    92 
       
    93 bool MessagePortChannel::isConnectedTo(MessagePort* port)
       
    94 {
       
    95     return m_channel->isConnectedTo(port);
       
    96 }
       
    97 
       
    98 bool MessagePortChannel::hasPendingActivity()
       
    99 {
       
   100     return m_channel->hasPendingActivity();
       
   101 }
       
   102 
       
   103 MessagePort* MessagePortChannel::locallyEntangledPort(const ScriptExecutionContext* context)
       
   104 {
       
   105     // This is just an optimization, so return 0 always.
       
   106     return 0;
       
   107 }
       
   108 
       
   109 
       
   110 PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::create()
       
   111 {
       
   112     return adoptRef(new PlatformMessagePortChannel());
       
   113 }
       
   114 
       
   115 PassRefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::create(
       
   116     WebMessagePortChannel* channel)
       
   117 {
       
   118     return adoptRef(new PlatformMessagePortChannel(channel));
       
   119 }
       
   120 
       
   121 
       
   122 PlatformMessagePortChannel::PlatformMessagePortChannel()
       
   123     : m_localPort(0)
       
   124 {
       
   125     m_webChannel = webKitClient()->createMessagePortChannel();
       
   126     if (m_webChannel)
       
   127         m_webChannel->setClient(this);
       
   128 }
       
   129 
       
   130 PlatformMessagePortChannel::PlatformMessagePortChannel(WebMessagePortChannel* channel)
       
   131     : m_localPort(0)
       
   132     , m_webChannel(channel)
       
   133 {
       
   134 }
       
   135 
       
   136 PlatformMessagePortChannel::~PlatformMessagePortChannel()
       
   137 {
       
   138     if (m_webChannel)
       
   139         m_webChannel->destroy();
       
   140 }
       
   141 
       
   142 void PlatformMessagePortChannel::createChannel(PassRefPtr<MessagePort> port1, PassRefPtr<MessagePort> port2)
       
   143 {
       
   144     // Create proxies for each endpoint.
       
   145     RefPtr<PlatformMessagePortChannel> channel1 = PlatformMessagePortChannel::create();
       
   146     RefPtr<PlatformMessagePortChannel> channel2 = PlatformMessagePortChannel::create();
       
   147 
       
   148     // Entangle the two endpoints.
       
   149     channel1->setEntangledChannel(channel2);
       
   150     channel2->setEntangledChannel(channel1);
       
   151 
       
   152     // Now entangle the proxies with the appropriate local ports.
       
   153     port1->entangle(MessagePortChannel::create(channel2));
       
   154     port2->entangle(MessagePortChannel::create(channel1));
       
   155 }
       
   156 
       
   157 void PlatformMessagePortChannel::messageAvailable()
       
   158 {
       
   159     MutexLocker lock(m_mutex);
       
   160     if (m_localPort)
       
   161         m_localPort->messageAvailable();
       
   162 }
       
   163 
       
   164 bool PlatformMessagePortChannel::entangleIfOpen(MessagePort* port)
       
   165 {
       
   166     MutexLocker lock(m_mutex);
       
   167     m_localPort = port;
       
   168     return true;
       
   169 }
       
   170 
       
   171 void PlatformMessagePortChannel::disentangle()
       
   172 {
       
   173     MutexLocker lock(m_mutex);
       
   174     m_localPort = 0;
       
   175 }
       
   176 
       
   177 void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message)
       
   178 {
       
   179     if (!m_localPort || !m_webChannel)
       
   180         return;
       
   181 
       
   182     WebString messageString = message->message()->toWireString();
       
   183     OwnPtr<WebCore::MessagePortChannelArray> channels = message->channels();
       
   184     WebMessagePortChannelArray* webChannels = 0;
       
   185     if (channels.get() && channels->size()) {
       
   186         webChannels = new WebMessagePortChannelArray(channels->size());
       
   187         for (size_t i = 0; i < channels->size(); ++i) {
       
   188             WebCore::PlatformMessagePortChannel* platformChannel = (*channels)[i]->channel();
       
   189             (*webChannels)[i] = platformChannel->webChannelRelease();
       
   190             (*webChannels)[i]->setClient(0);
       
   191         }
       
   192     }
       
   193     m_webChannel->postMessage(messageString, webChannels);
       
   194 }
       
   195 
       
   196 bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtr<MessagePortChannel::EventData>& result)
       
   197 {
       
   198     if (!m_webChannel)
       
   199         return false;
       
   200 
       
   201     WebString message;
       
   202     WebMessagePortChannelArray webChannels;
       
   203     bool rv = m_webChannel->tryGetMessage(&message, webChannels);
       
   204     if (rv) {
       
   205         OwnPtr<MessagePortChannelArray> channels;
       
   206         if (webChannels.size()) {
       
   207             channels = new MessagePortChannelArray(webChannels.size());
       
   208             for (size_t i = 0; i < webChannels.size(); ++i) {
       
   209                 RefPtr<PlatformMessagePortChannel> platformChannel = create(webChannels[i]);
       
   210                 webChannels[i]->setClient(platformChannel.get());
       
   211                 (*channels)[i] = MessagePortChannel::create(platformChannel);
       
   212             }
       
   213         }
       
   214         RefPtr<SerializedScriptValue> serializedMessage = SerializedScriptValue::createFromWire(message);
       
   215         result = MessagePortChannel::EventData::create(serializedMessage.release(), channels.release());
       
   216     }
       
   217 
       
   218     return rv;
       
   219 }
       
   220 
       
   221 void PlatformMessagePortChannel::close()
       
   222 {
       
   223     MutexLocker lock(m_mutex);
       
   224     // Disentangle ourselves from the other end.  We still maintain a reference to m_webChannel,
       
   225     // since previously-existing messages should still be delivered.
       
   226     m_localPort = 0;
       
   227     m_entangledChannel = 0;
       
   228 }
       
   229 
       
   230 bool PlatformMessagePortChannel::isConnectedTo(MessagePort* port)
       
   231 {
       
   232     MutexLocker lock(m_mutex);
       
   233     return m_entangledChannel && m_entangledChannel->m_localPort == port;
       
   234 }
       
   235 
       
   236 bool PlatformMessagePortChannel::hasPendingActivity()
       
   237 {
       
   238     MutexLocker lock(m_mutex);
       
   239     return m_localPort;
       
   240 }
       
   241 
       
   242 void PlatformMessagePortChannel::setEntangledChannel(PassRefPtr<PlatformMessagePortChannel> remote)
       
   243 {
       
   244     if (m_webChannel)
       
   245         m_webChannel->entangle(remote->m_webChannel);
       
   246 
       
   247     MutexLocker lock(m_mutex);
       
   248     m_entangledChannel = remote;
       
   249 }
       
   250 
       
   251 WebMessagePortChannel* PlatformMessagePortChannel::webChannelRelease()
       
   252 {
       
   253     WebMessagePortChannel* rv = m_webChannel;
       
   254     m_webChannel = 0;
       
   255     return rv;
       
   256 }
       
   257 
       
   258 } // namespace WebCore