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, std::make_unique<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) |
232 | |