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