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