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 "NPObjectMessageReceiver.h"
28
29#if ENABLE(NETSCAPE_PLUGIN_API)
30
31#include "NPIdentifierData.h"
32#include "NPRemoteObjectMap.h"
33#include "NPRuntimeUtilities.h"
34#include "NPVariantData.h"
35#include "Plugin.h"
36#include "PluginController.h"
37
38namespace WebKit {
39
40NPObjectMessageReceiver::NPObjectMessageReceiver(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID, NPObject* npObject)
41 : m_npRemoteObjectMap(npRemoteObjectMap)
42 , m_plugin(plugin)
43 , m_npObjectID(npObjectID)
44 , m_npObject(npObject)
45{
46 retainNPObject(m_npObject);
47}
48
49NPObjectMessageReceiver::~NPObjectMessageReceiver()
50{
51 m_npRemoteObjectMap->unregisterNPObject(m_npObjectID);
52
53 releaseNPObject(m_npObject);
54}
55
56void NPObjectMessageReceiver::deallocate(CompletionHandler<void()>&& completionHandler)
57{
58 delete this;
59 completionHandler();
60}
61
62void NPObjectMessageReceiver::hasMethod(const NPIdentifierData& methodNameData, CompletionHandler<void(bool)>&& completionHandler)
63{
64 if (m_plugin->isBeingDestroyed() || !m_npObject->_class->hasMethod)
65 return completionHandler(false);
66
67 completionHandler(m_npObject->_class->hasMethod(m_npObject, methodNameData.createNPIdentifier()));
68}
69
70void NPObjectMessageReceiver::invoke(const NPIdentifierData& methodNameData, const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
71{
72 if (m_plugin->isBeingDestroyed() || !m_npObject->_class->invoke)
73 return completionHandler(false, { });
74
75 Vector<NPVariant> arguments;
76 for (size_t i = 0; i < argumentsData.size(); ++i)
77 arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
78
79 NPVariant result;
80 VOID_TO_NPVARIANT(result);
81
82 PluginController::PluginDestructionProtector protector(m_plugin->controller());
83
84 NPVariantData resultData;
85 bool returnValue = m_npObject->_class->invoke(m_npObject, methodNameData.createNPIdentifier(), arguments.data(), arguments.size(), &result);
86 if (returnValue) {
87 // Convert the NPVariant to an NPVariantData.
88 resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
89 }
90
91 // Release all arguments.
92 for (size_t i = 0; i < argumentsData.size(); ++i)
93 releaseNPVariantValue(&arguments[i]);
94
95 // And release the result.
96 releaseNPVariantValue(&result);
97 completionHandler(returnValue, WTFMove(resultData));
98}
99
100void NPObjectMessageReceiver::invokeDefault(const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
101{
102 if (m_plugin->isBeingDestroyed() || !m_npObject->_class->invokeDefault)
103 return completionHandler(false, { });
104
105 Vector<NPVariant> arguments;
106 for (size_t i = 0; i < argumentsData.size(); ++i)
107 arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
108
109 NPVariant result;
110 VOID_TO_NPVARIANT(result);
111
112 PluginController::PluginDestructionProtector protector(m_plugin->controller());
113
114 NPVariantData resultData;
115 bool returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), arguments.size(), &result);
116 if (returnValue) {
117 // Convert the NPVariant to an NPVariantData.
118 resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
119 }
120
121 // Release all arguments.
122 for (size_t i = 0; i < argumentsData.size(); ++i)
123 releaseNPVariantValue(&arguments[i]);
124
125 // And release the result.
126 releaseNPVariantValue(&result);
127 completionHandler(returnValue, WTFMove(resultData));
128}
129
130void NPObjectMessageReceiver::hasProperty(const NPIdentifierData& propertyNameData, CompletionHandler<void(bool)>&& completionHandler)
131{
132 if (m_plugin->isBeingDestroyed() || !m_npObject->_class->hasProperty)
133 return completionHandler(false);
134
135 completionHandler(m_npObject->_class->hasProperty(m_npObject, propertyNameData.createNPIdentifier()));
136}
137
138void NPObjectMessageReceiver::getProperty(const NPIdentifierData& propertyNameData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
139{
140 if (m_plugin->isBeingDestroyed() || !m_npObject->_class->getProperty)
141 return completionHandler(false, { });
142
143 NPVariant result;
144 VOID_TO_NPVARIANT(result);
145
146 PluginController::PluginDestructionProtector protector(m_plugin->controller());
147
148 bool returnValue = m_npObject->_class->getProperty(m_npObject, propertyNameData.createNPIdentifier(), &result);
149 if (!returnValue)
150 return completionHandler(false, { });
151
152
153 NPVariantData resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
154
155 releaseNPVariantValue(&result);
156 completionHandler(true, WTFMove(resultData));
157}
158
159void NPObjectMessageReceiver::setProperty(const NPIdentifierData& propertyNameData, const NPVariantData& propertyValueData, CompletionHandler<void(bool)>&& completionHandler)
160{
161 if (m_plugin->isBeingDestroyed() || !m_npObject->_class->setProperty)
162 return completionHandler(false);
163
164 NPVariant propertyValue = m_npRemoteObjectMap->npVariantDataToNPVariant(propertyValueData, m_plugin);
165
166 PluginController::PluginDestructionProtector protector(m_plugin->controller());
167
168 bool returnValue = m_npObject->_class->setProperty(m_npObject, propertyNameData.createNPIdentifier(), &propertyValue);
169
170 releaseNPVariantValue(&propertyValue);
171 completionHandler(returnValue);
172}
173
174void NPObjectMessageReceiver::removeProperty(const NPIdentifierData& propertyNameData, CompletionHandler<void(bool)>&& completionHandler)
175{
176 if (m_plugin->isBeingDestroyed() || !m_npObject->_class->removeProperty)
177 return completionHandler(false);
178
179 completionHandler(m_npObject->_class->removeProperty(m_npObject, propertyNameData.createNPIdentifier()));
180}
181
182void NPObjectMessageReceiver::enumerate(CompletionHandler<void(bool, Vector<NPIdentifierData>&&)>&& completionHandler)
183{
184 if (m_plugin->isBeingDestroyed() || !NP_CLASS_STRUCT_VERSION_HAS_ENUM(m_npObject->_class) || !m_npObject->_class->enumerate)
185 return completionHandler(false, { });
186
187 NPIdentifier* identifiers = 0;
188 uint32_t identifierCount = 0;
189
190 bool returnValue = m_npObject->_class->enumerate(m_npObject, &identifiers, &identifierCount);
191 if (!returnValue)
192 return completionHandler(false, { });
193
194 Vector<WebKit::NPIdentifierData> identifiersData;
195 for (uint32_t i = 0; i < identifierCount; ++i)
196 identifiersData.append(NPIdentifierData::fromNPIdentifier(identifiers[i]));
197
198 npnMemFree(identifiers);
199 completionHandler(true, WTFMove(identifiersData));
200}
201
202void NPObjectMessageReceiver::construct(const Vector<NPVariantData>& argumentsData, CompletionHandler<void(bool, NPVariantData&&)>&& completionHandler)
203{
204 if (m_plugin->isBeingDestroyed() || !NP_CLASS_STRUCT_VERSION_HAS_CTOR(m_npObject->_class) || !m_npObject->_class->construct)
205 return completionHandler(false, { });
206
207 Vector<NPVariant> arguments;
208 for (size_t i = 0; i < argumentsData.size(); ++i)
209 arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
210
211 NPVariant result;
212 VOID_TO_NPVARIANT(result);
213
214 PluginController::PluginDestructionProtector protector(m_plugin->controller());
215
216 bool returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), arguments.size(), &result);
217 NPVariantData resultData;
218 if (returnValue)
219 resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
220
221 for (size_t i = 0; i < argumentsData.size(); ++i)
222 releaseNPVariantValue(&arguments[i]);
223
224 releaseNPVariantValue(&result);
225 completionHandler(returnValue, WTFMove(resultData));
226}
227
228} // namespace WebKit
229
230#endif // ENABLE(NETSCAPE_PLUGIN_API)
231
232