NPRemoteObjectMap.cpp revision 65f03d4f644ce73618e5f4f50dd694b26f55ae12
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#if ENABLE(PLUGIN_PROCESS) 27 28#include "NPRemoteObjectMap.h" 29 30#include "NPObjectMessageReceiver.h" 31#include "NPObjectProxy.h" 32#include "NPRuntimeUtilities.h" 33#include "NPVariantData.h" 34#include "NotImplemented.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 , m_isInvalidating(false) 53{ 54} 55 56NPRemoteObjectMap::~NPRemoteObjectMap() 57{ 58 ASSERT(m_npObjectProxies.isEmpty()); 59 ASSERT(m_registeredNPObjects.isEmpty()); 60} 61 62NPObject* NPRemoteObjectMap::createNPObjectProxy(uint64_t remoteObjectID) 63{ 64 NPObjectProxy* npObjectProxy = NPObjectProxy::create(this, remoteObjectID); 65 66 m_npObjectProxies.add(npObjectProxy); 67 68 return npObjectProxy; 69} 70 71void NPRemoteObjectMap::npObjectProxyDestroyed(NPObject* npObject) 72{ 73 ASSERT(NPObjectProxy::isNPObjectProxy(npObject)); 74 ASSERT(m_npObjectProxies.contains(npObject)); 75 76 m_npObjectProxies.remove(npObject); 77} 78 79uint64_t NPRemoteObjectMap::registerNPObject(NPObject* npObject) 80{ 81 uint64_t npObjectID = generateNPObjectID(); 82 m_registeredNPObjects.set(npObjectID, NPObjectMessageReceiver::create(this, npObjectID, npObject).leakPtr()); 83 84 return npObjectID; 85} 86 87void NPRemoteObjectMap::unregisterNPObject(uint64_t npObjectID) 88{ 89 m_registeredNPObjects.remove(npObjectID); 90} 91 92NPVariantData NPRemoteObjectMap::npVariantToNPVariantData(const NPVariant& variant) 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); 127 return NPVariantData::makeLocalNPObjectID(npObjectID); 128 } 129 130 } 131 132 ASSERT_NOT_REACHED(); 133 return NPVariantData::makeVoid(); 134} 135 136NPVariant NPRemoteObjectMap::npVariantDataToNPVariant(const NPVariantData& npVariantData) 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()); 181 OBJECT_TO_NPVARIANT(npObjectProxy, npVariant); 182 break; 183 } 184 } 185 186 return npVariant; 187} 188 189void NPRemoteObjectMap::invalidate() 190{ 191 ASSERT(!m_isInvalidating); 192 193 m_isInvalidating = true; 194 195 Vector<NPObjectMessageReceiver*> messageReceivers; 196 copyValuesToVector(m_registeredNPObjects, messageReceivers); 197 198 // Now delete all the receivers. 199 deleteAllValues(messageReceivers); 200 201 ASSERT(m_registeredNPObjects.isEmpty()); 202 203 for (HashSet<NPObject*>::const_iterator it = m_npObjectProxies.begin(), end = m_npObjectProxies.end(); it != end; ++it) 204 NPObjectProxy::toNPObjectProxy(*it)->invalidate(); 205 m_npObjectProxies.clear(); 206 207 m_isInvalidating = false; 208} 209 210CoreIPC::SyncReplyMode NPRemoteObjectMap::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply) 211{ 212 NPObjectMessageReceiver* messageReceiver = m_registeredNPObjects.get(arguments->destinationID()); 213 if (!messageReceiver) 214 return CoreIPC::AutomaticReply; 215 216 return messageReceiver->didReceiveSyncNPObjectMessageReceiverMessage(connection, messageID, arguments, reply); 217} 218 219} // namespace WebKit 220 221#endif // ENABLE(PLUGIN_PROCESS) 222