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