Home | History | Annotate | Download | only in Plugins
      1 /*
      2  * Copyright (C) 2010 Apple 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
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "NPRemoteObjectMap.h"
     28 
     29 #if ENABLE(PLUGIN_PROCESS)
     30 
     31 #include "NPObjectMessageReceiver.h"
     32 #include "NPObjectProxy.h"
     33 #include "NPRuntimeUtilities.h"
     34 #include "NPVariantData.h"
     35 #include <WebCore/NotImplemented.h>
     36 #include <wtf/OwnPtr.h>
     37 
     38 namespace WebKit {
     39 
     40 static uint64_t generateNPObjectID()
     41 {
     42     static uint64_t generateNPObjectID;
     43     return ++generateNPObjectID;
     44 }
     45 
     46 PassRefPtr<NPRemoteObjectMap> NPRemoteObjectMap::create(CoreIPC::Connection* connection)
     47 {
     48     return adoptRef(new NPRemoteObjectMap(connection));
     49 }
     50 
     51 NPRemoteObjectMap::NPRemoteObjectMap(CoreIPC::Connection* connection)
     52     : m_connection(connection)
     53 {
     54 }
     55 
     56 NPRemoteObjectMap::~NPRemoteObjectMap()
     57 {
     58     ASSERT(m_npObjectProxies.isEmpty());
     59     ASSERT(m_registeredNPObjects.isEmpty());
     60 }
     61 
     62 NPObject* NPRemoteObjectMap::createNPObjectProxy(uint64_t remoteObjectID, Plugin* plugin)
     63 {
     64     NPObjectProxy* npObjectProxy = NPObjectProxy::create(this, plugin, remoteObjectID);
     65 
     66     m_npObjectProxies.add(npObjectProxy);
     67 
     68     return npObjectProxy;
     69 }
     70 
     71 void NPRemoteObjectMap::npObjectProxyDestroyed(NPObject* npObject)
     72 {
     73     NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject);
     74     ASSERT(m_npObjectProxies.contains(npObjectProxy));
     75 
     76     m_npObjectProxies.remove(npObjectProxy);
     77 }
     78 
     79 uint64_t NPRemoteObjectMap::registerNPObject(NPObject* npObject, Plugin* plugin)
     80 {
     81     uint64_t npObjectID = generateNPObjectID();
     82     m_registeredNPObjects.set(npObjectID, NPObjectMessageReceiver::create(this, plugin, npObjectID, npObject).leakPtr());
     83 
     84     return npObjectID;
     85 }
     86 
     87 void NPRemoteObjectMap::unregisterNPObject(uint64_t npObjectID)
     88 {
     89     m_registeredNPObjects.remove(npObjectID);
     90 }
     91 
     92 NPVariantData NPRemoteObjectMap::npVariantToNPVariantData(const NPVariant& variant, Plugin* plugin)
     93 {
     94     switch (variant.type) {
     95     case NPVariantType_Void:
     96         return NPVariantData::makeVoid();
     97 
     98     case NPVariantType_Null:
     99         return NPVariantData::makeNull();
    100 
    101     case NPVariantType_Bool:
    102         return NPVariantData::makeBool(variant.value.boolValue);
    103 
    104     case NPVariantType_Int32:
    105         return NPVariantData::makeInt32(variant.value.intValue);
    106 
    107     case NPVariantType_Double:
    108         return NPVariantData::makeDouble(variant.value.doubleValue);
    109 
    110     case NPVariantType_String:
    111         return NPVariantData::makeString(variant.value.stringValue.UTF8Characters, variant.value.stringValue.UTF8Length);
    112 
    113     case NPVariantType_Object: {
    114         NPObject* npObject = variant.value.objectValue;
    115         if (NPObjectProxy::isNPObjectProxy(npObject)) {
    116             NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject);
    117 
    118             uint64_t npObjectID = npObjectProxy->npObjectID();
    119 
    120             // FIXME: Under some circumstances, this might leak the NPObjectProxy object.
    121             // Figure out how to avoid that.
    122             retainNPObject(npObjectProxy);
    123             return NPVariantData::makeRemoteNPObjectID(npObjectID);
    124         }
    125 
    126         uint64_t npObjectID = registerNPObject(npObject, plugin);
    127         return NPVariantData::makeLocalNPObjectID(npObjectID);
    128     }
    129 
    130     }
    131 
    132     ASSERT_NOT_REACHED();
    133     return NPVariantData::makeVoid();
    134 }
    135 
    136 NPVariant NPRemoteObjectMap::npVariantDataToNPVariant(const NPVariantData& npVariantData, Plugin* plugin)
    137 {
    138     NPVariant npVariant;
    139 
    140     switch (npVariantData.type()) {
    141     case NPVariantData::Void:
    142         VOID_TO_NPVARIANT(npVariant);
    143         break;
    144     case NPVariantData::Null:
    145         NULL_TO_NPVARIANT(npVariant);
    146         break;
    147     case NPVariantData::Bool:
    148         BOOLEAN_TO_NPVARIANT(npVariantData.boolValue(), npVariant);
    149         break;
    150     case NPVariantData::Int32:
    151         INT32_TO_NPVARIANT(npVariantData.int32Value(), npVariant);
    152         break;
    153     case NPVariantData::Double:
    154         DOUBLE_TO_NPVARIANT(npVariantData.doubleValue(), npVariant);
    155         break;
    156     case NPVariantData::String: {
    157         NPString npString = createNPString(npVariantData.stringValue());
    158         STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, npVariant);
    159         break;
    160     }
    161     case NPVariantData::LocalNPObjectID: {
    162         uint64_t npObjectID = npVariantData.localNPObjectIDValue();
    163         ASSERT(npObjectID);
    164 
    165         NPObjectMessageReceiver* npObjectMessageReceiver = m_registeredNPObjects.get(npObjectID);
    166         if (!npObjectMessageReceiver) {
    167             ASSERT_NOT_REACHED();
    168             VOID_TO_NPVARIANT(npVariant);
    169             break;
    170         }
    171 
    172         NPObject* npObject = npObjectMessageReceiver->npObject();
    173         ASSERT(npObject);
    174 
    175         retainNPObject(npObject);
    176         OBJECT_TO_NPVARIANT(npObject, npVariant);
    177         break;
    178     }
    179     case NPVariantData::RemoteNPObjectID: {
    180         NPObject* npObjectProxy = createNPObjectProxy(npVariantData.remoteNPObjectIDValue(), plugin);
    181         OBJECT_TO_NPVARIANT(npObjectProxy, npVariant);
    182         break;
    183     }
    184     }
    185 
    186     return npVariant;
    187 }
    188 
    189 void NPRemoteObjectMap::pluginDestroyed(Plugin* plugin)
    190 {
    191     Vector<NPObjectMessageReceiver*> messageReceivers;
    192 
    193     // Gather the receivers associated with this plug-in.
    194     for (HashMap<uint64_t, NPObjectMessageReceiver*>::const_iterator it = m_registeredNPObjects.begin(), end = m_registeredNPObjects.end(); it != end; ++it) {
    195         NPObjectMessageReceiver* npObjectMessageReceiver = it->second;
    196         if (npObjectMessageReceiver->plugin() == plugin)
    197             messageReceivers.append(npObjectMessageReceiver);
    198     }
    199 
    200     // Now delete all the receivers.
    201     deleteAllValues(messageReceivers);
    202 
    203     Vector<NPObjectProxy*> objectProxies;
    204     for (HashSet<NPObjectProxy*>::const_iterator it = m_npObjectProxies.begin(), end = m_npObjectProxies.end(); it != end; ++it) {
    205         NPObjectProxy* npObjectProxy = *it;
    206 
    207         if (npObjectProxy->plugin() == plugin)
    208             objectProxies.append(npObjectProxy);
    209     }
    210 
    211     // Invalidate and remove all proxies associated with this plug-in.
    212     for (size_t i = 0; i < objectProxies.size(); ++i) {
    213         NPObjectProxy* npObjectProxy = objectProxies[i];
    214 
    215         npObjectProxy->invalidate();
    216 
    217         ASSERT(m_npObjectProxies.contains(npObjectProxy));
    218         m_npObjectProxies.remove(npObjectProxy);
    219     }
    220 }
    221 
    222 CoreIPC::SyncReplyMode NPRemoteObjectMap::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
    223 {
    224     NPObjectMessageReceiver* messageReceiver = m_registeredNPObjects.get(arguments->destinationID());
    225     if (!messageReceiver)
    226         return CoreIPC::AutomaticReply;
    227 
    228     return messageReceiver->didReceiveSyncNPObjectMessageReceiverMessage(connection, messageID, arguments, reply);
    229 }
    230 
    231 } // namespace WebKit
    232 
    233 #endif // ENABLE(PLUGIN_PROCESS)
    234