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