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