NPRemoteObjectMap.cpp revision 81bc750723a18f21cd17d1b173cd2a4dda9cea6e
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
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