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 <wtf/OwnPtr.h> 36 37namespace WebKit { 38 39static uint64_t generateNPObjectID() 40{ 41 static uint64_t generateNPObjectID; 42 return ++generateNPObjectID; 43} 44 45PassRefPtr<NPRemoteObjectMap> NPRemoteObjectMap::create(CoreIPC::Connection* connection) 46{ 47 return adoptRef(new NPRemoteObjectMap(connection)); 48} 49 50NPRemoteObjectMap::NPRemoteObjectMap(CoreIPC::Connection* connection) 51 : m_connection(connection) 52{ 53} 54 55NPRemoteObjectMap::~NPRemoteObjectMap() 56{ 57 ASSERT(m_npObjectProxies.isEmpty()); 58 ASSERT(m_registeredNPObjects.isEmpty()); 59} 60 61NPObject* NPRemoteObjectMap::createNPObjectProxy(uint64_t remoteObjectID, Plugin* plugin) 62{ 63 NPObjectProxy* npObjectProxy = NPObjectProxy::create(this, plugin, remoteObjectID); 64 65 m_npObjectProxies.add(npObjectProxy); 66 67 return npObjectProxy; 68} 69 70void NPRemoteObjectMap::npObjectProxyDestroyed(NPObject* npObject) 71{ 72 NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject); 73 ASSERT(m_npObjectProxies.contains(npObjectProxy)); 74 75 m_npObjectProxies.remove(npObjectProxy); 76} 77 78uint64_t NPRemoteObjectMap::registerNPObject(NPObject* npObject, Plugin* plugin) 79{ 80 uint64_t npObjectID = generateNPObjectID(); 81 m_registeredNPObjects.set(npObjectID, NPObjectMessageReceiver::create(this, plugin, npObjectID, npObject).leakPtr()); 82 83 return npObjectID; 84} 85 86void NPRemoteObjectMap::unregisterNPObject(uint64_t npObjectID) 87{ 88 m_registeredNPObjects.remove(npObjectID); 89} 90 91static uint64_t remoteNPObjectID(Plugin* plugin, NPObject* npObject) 92{ 93 if (!NPObjectProxy::isNPObjectProxy(npObject)) 94 return 0; 95 96 NPObjectProxy* npObjectProxy = NPObjectProxy::toNPObjectProxy(npObject); 97 if (npObjectProxy->plugin() != plugin) 98 return 0; 99 100 return npObjectProxy->npObjectID(); 101} 102 103NPVariantData NPRemoteObjectMap::npVariantToNPVariantData(const NPVariant& variant, Plugin* plugin) 104{ 105 switch (variant.type) { 106 case NPVariantType_Void: 107 return NPVariantData::makeVoid(); 108 109 case NPVariantType_Null: 110 return NPVariantData::makeNull(); 111 112 case NPVariantType_Bool: 113 return NPVariantData::makeBool(variant.value.boolValue); 114 115 case NPVariantType_Int32: 116 return NPVariantData::makeInt32(variant.value.intValue); 117 118 case NPVariantType_Double: 119 return NPVariantData::makeDouble(variant.value.doubleValue); 120 121 case NPVariantType_String: 122 return NPVariantData::makeString(variant.value.stringValue.UTF8Characters, variant.value.stringValue.UTF8Length); 123 124 case NPVariantType_Object: { 125 NPObject* npObject = variant.value.objectValue; 126 127 if (uint64_t npObjectID = remoteNPObjectID(plugin, npObject)) { 128 // FIXME: Under some circumstances, this might leak the NPObjectProxy object. 129 // Figure out how to avoid that. 130 retainNPObject(npObject); 131 return NPVariantData::makeRemoteNPObjectID(npObjectID); 132 } 133 134 uint64_t npObjectID = registerNPObject(npObject, plugin); 135 return NPVariantData::makeLocalNPObjectID(npObjectID); 136 } 137 138 } 139 140 ASSERT_NOT_REACHED(); 141 return NPVariantData::makeVoid(); 142} 143 144NPVariant NPRemoteObjectMap::npVariantDataToNPVariant(const NPVariantData& npVariantData, Plugin* plugin) 145{ 146 NPVariant npVariant; 147 148 switch (npVariantData.type()) { 149 case NPVariantData::Void: 150 VOID_TO_NPVARIANT(npVariant); 151 break; 152 case NPVariantData::Null: 153 NULL_TO_NPVARIANT(npVariant); 154 break; 155 case NPVariantData::Bool: 156 BOOLEAN_TO_NPVARIANT(npVariantData.boolValue(), npVariant); 157 break; 158 case NPVariantData::Int32: 159 INT32_TO_NPVARIANT(npVariantData.int32Value(), npVariant); 160 break; 161 case NPVariantData::Double: 162 DOUBLE_TO_NPVARIANT(npVariantData.doubleValue(), npVariant); 163 break; 164 case NPVariantData::String: { 165 NPString npString = createNPString(npVariantData.stringValue()); 166 STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, npVariant); 167 break; 168 } 169 case NPVariantData::LocalNPObjectID: { 170 uint64_t npObjectID = npVariantData.localNPObjectIDValue(); 171 ASSERT(npObjectID); 172 173 NPObjectMessageReceiver* npObjectMessageReceiver = m_registeredNPObjects.get(npObjectID); 174 if (!npObjectMessageReceiver) { 175 ASSERT_NOT_REACHED(); 176 VOID_TO_NPVARIANT(npVariant); 177 break; 178 } 179 180 NPObject* npObject = npObjectMessageReceiver->npObject(); 181 ASSERT(npObject); 182 183 retainNPObject(npObject); 184 OBJECT_TO_NPVARIANT(npObject, npVariant); 185 break; 186 } 187 case NPVariantData::RemoteNPObjectID: { 188 NPObject* npObjectProxy = createNPObjectProxy(npVariantData.remoteNPObjectIDValue(), plugin); 189 OBJECT_TO_NPVARIANT(npObjectProxy, npVariant); 190 break; 191 } 192 } 193 194 return npVariant; 195} 196 197void NPRemoteObjectMap::pluginDestroyed(Plugin* plugin) 198{ 199 Vector<NPObjectMessageReceiver*> messageReceivers; 200 201 // Gather the receivers associated with this plug-in. 202 for (HashMap<uint64_t, NPObjectMessageReceiver*>::const_iterator it = m_registeredNPObjects.begin(), end = m_registeredNPObjects.end(); it != end; ++it) { 203 NPObjectMessageReceiver* npObjectMessageReceiver = it->value; 204 if (npObjectMessageReceiver->plugin() == plugin) 205 messageReceivers.append(npObjectMessageReceiver); 206 } 207 208 // Now delete all the receivers. 209 deleteAllValues(messageReceivers); 210 211 Vector<NPObjectProxy*> objectProxies; 212 for (HashSet<NPObjectProxy*>::const_iterator it = m_npObjectProxies.begin(), end = m_npObjectProxies.end(); it != end; ++it) { 213 NPObjectProxy* npObjectProxy = *it; 214 215 if (npObjectProxy->plugin() == plugin) 216 objectProxies.append(npObjectProxy); 217 } 218 219 // Invalidate and remove all proxies associated with this plug-in. 220 for (size_t i = 0; i < objectProxies.size(); ++i) { 221 NPObjectProxy* npObjectProxy = objectProxies[i]; 222 223 npObjectProxy->invalidate(); 224 225 ASSERT(m_npObjectProxies.contains(npObjectProxy)); 226 m_npObjectProxies.remove(npObjectProxy); 227 } 228} 229 230void NPRemoteObjectMap::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder) 231{ 232 NPObjectMessageReceiver* messageReceiver = m_registeredNPObjects.get(decoder.destinationID()); 233 if (!messageReceiver) 234 return; 235 236 messageReceiver->didReceiveSyncNPObjectMessageReceiverMessage(connection, decoder, replyEncoder); 237} 238 239} // namespace WebKit 240 241#endif // ENABLE(PLUGIN_PROCESS) 242