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 "NPObjectProxy.h"
28
29#if ENABLE(PLUGIN_PROCESS)
30
31#include "ArgumentCoders.h"
32#include "Connection.h"
33#include "NPIdentifierData.h"
34#include "NPObjectMessageReceiverMessages.h"
35#include "NPRemoteObjectMap.h"
36#include "NPRuntimeUtilities.h"
37#include "NPVariantData.h"
38
39namespace WebKit {
40
41NPObjectProxy* NPObjectProxy::create(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID)
42{
43    NPObjectProxy* npObjectProxy = toNPObjectProxy(createNPObject(0, npClass()));
44    npObjectProxy->initialize(npRemoteObjectMap, plugin, npObjectID);
45
46    return npObjectProxy;
47}
48
49NPObjectProxy::NPObjectProxy()
50    : m_npRemoteObjectMap(0)
51    , m_plugin(0)
52    , m_npObjectID(0)
53{
54}
55
56NPObjectProxy::~NPObjectProxy()
57{
58    if (!m_npRemoteObjectMap)
59        return;
60
61    m_npRemoteObjectMap->npObjectProxyDestroyed(this);
62    m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Deallocate(), Messages::NPObjectMessageReceiver::Deallocate::Reply(), m_npObjectID);
63}
64
65bool NPObjectProxy::isNPObjectProxy(NPObject* npObject)
66{
67    return npObject->_class == npClass();
68}
69
70void NPObjectProxy::invalidate()
71{
72    ASSERT(m_npRemoteObjectMap);
73    ASSERT(m_plugin);
74
75    m_npRemoteObjectMap = 0;
76    m_plugin = 0;
77}
78
79void NPObjectProxy::initialize(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID)
80{
81    ASSERT(!m_npRemoteObjectMap);
82    ASSERT(!m_plugin);
83    ASSERT(!m_npObjectID);
84
85    ASSERT(npRemoteObjectMap);
86    ASSERT(plugin);
87    ASSERT(npObjectID);
88
89    m_npRemoteObjectMap = npRemoteObjectMap;
90    m_plugin = plugin;
91    m_npObjectID = npObjectID;
92}
93
94bool NPObjectProxy::hasMethod(NPIdentifier methodName)
95{
96    if (!m_npRemoteObjectMap)
97        return false;
98
99    NPIdentifierData methodNameData = NPIdentifierData::fromNPIdentifier(methodName);
100
101    bool returnValue = false;
102
103    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::HasMethod(methodNameData), Messages::NPObjectMessageReceiver::HasMethod::Reply(returnValue), m_npObjectID))
104        return false;
105
106    return returnValue;
107}
108
109bool NPObjectProxy::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
110{
111    if (!m_npRemoteObjectMap)
112        return false;
113
114    NPIdentifierData methodNameData = NPIdentifierData::fromNPIdentifier(methodName);
115    Vector<NPVariantData> argumentsData;
116    for (uint32_t i = 0; i < argumentCount; ++i)
117        argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
118
119    bool returnValue = false;
120    NPVariantData resultData;
121
122    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Invoke(methodNameData, argumentsData), Messages::NPObjectMessageReceiver::Invoke::Reply(returnValue, resultData), m_npObjectID))
123        return false;
124
125    if (!returnValue)
126        return false;
127
128    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
129    return true;
130}
131
132bool NPObjectProxy::invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
133{
134    if (!m_npRemoteObjectMap)
135        return false;
136
137    Vector<NPVariantData> argumentsData;
138    for (uint32_t i = 0; i < argumentCount; ++i)
139        argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
140
141    bool returnValue = false;
142    NPVariantData resultData;
143
144    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::InvokeDefault(argumentsData), Messages::NPObjectMessageReceiver::InvokeDefault::Reply(returnValue, resultData), m_npObjectID))
145        return false;
146
147    if (!returnValue)
148        return false;
149
150    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
151    return true;
152}
153
154bool NPObjectProxy::hasProperty(NPIdentifier propertyName)
155{
156    if (!m_npRemoteObjectMap)
157        return false;
158
159    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
160
161    bool returnValue = false;
162
163    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::HasProperty(propertyNameData), Messages::NPObjectMessageReceiver::HasProperty::Reply(returnValue), m_npObjectID))
164        return false;
165
166    return returnValue;
167}
168
169bool NPObjectProxy::getProperty(NPIdentifier propertyName, NPVariant* result)
170{
171    if (!m_npRemoteObjectMap)
172        return false;
173
174    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
175
176    bool returnValue = false;
177    NPVariantData resultData;
178
179    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::GetProperty(propertyNameData), Messages::NPObjectMessageReceiver::GetProperty::Reply(returnValue, resultData), m_npObjectID))
180        return false;
181
182    if (!returnValue)
183        return false;
184
185    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
186    return true;
187}
188
189bool NPObjectProxy::setProperty(NPIdentifier propertyName, const NPVariant* value)
190{
191    if (!m_npRemoteObjectMap)
192        return false;
193
194    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
195    NPVariantData propertyValueData = m_npRemoteObjectMap->npVariantToNPVariantData(*value, m_plugin);
196
197    bool returnValue = false;
198
199    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::SetProperty(propertyNameData, propertyValueData), Messages::NPObjectMessageReceiver::SetProperty::Reply(returnValue), m_npObjectID))
200        return false;
201
202    return returnValue;
203}
204
205bool NPObjectProxy::removeProperty(NPIdentifier propertyName)
206{
207    if (!m_npRemoteObjectMap)
208        return false;
209
210    NPIdentifierData propertyNameData = NPIdentifierData::fromNPIdentifier(propertyName);
211
212    bool returnValue = false;
213
214    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::RemoveProperty(propertyNameData), Messages::NPObjectMessageReceiver::RemoveProperty::Reply(returnValue), m_npObjectID))
215        return false;
216
217    return returnValue;
218}
219
220bool NPObjectProxy::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount)
221{
222    if (!m_npRemoteObjectMap)
223        return false;
224
225    bool returnValue;
226    Vector<NPIdentifierData> identifiersData;
227
228    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Enumerate(), Messages::NPObjectMessageReceiver::Enumerate::Reply(returnValue, identifiersData), m_npObjectID))
229        return false;
230
231    if (!returnValue)
232        return false;
233
234    NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(identifiersData.size());
235
236    for (size_t i = 0; i < identifiersData.size(); ++i)
237        nameIdentifiers[i] = identifiersData[i].createNPIdentifier();
238
239    *identifiers = nameIdentifiers;
240    *identifierCount = identifiersData.size();
241    return true;
242}
243
244bool NPObjectProxy::construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
245{
246    if (!m_npRemoteObjectMap)
247        return false;
248
249    Vector<NPVariantData> argumentsData;
250    for (uint32_t i = 0; i < argumentCount; ++i)
251        argumentsData.append(m_npRemoteObjectMap->npVariantToNPVariantData(arguments[i], m_plugin));
252
253    bool returnValue = false;
254    NPVariantData resultData;
255
256    if (!m_npRemoteObjectMap->connection()->sendSync(Messages::NPObjectMessageReceiver::Construct(argumentsData), Messages::NPObjectMessageReceiver::Construct::Reply(returnValue, resultData), m_npObjectID))
257        return false;
258
259    if (!returnValue)
260        return false;
261
262    *result = m_npRemoteObjectMap->npVariantDataToNPVariant(resultData, m_plugin);
263    return true;
264}
265
266NPClass* NPObjectProxy::npClass()
267{
268    static NPClass npClass = {
269        NP_CLASS_STRUCT_VERSION,
270        NP_Allocate,
271        NP_Deallocate,
272        0,
273        NP_HasMethod,
274        NP_Invoke,
275        NP_InvokeDefault,
276        NP_HasProperty,
277        NP_GetProperty,
278        NP_SetProperty,
279        NP_RemoveProperty,
280        NP_Enumerate,
281        NP_Construct
282    };
283
284    return &npClass;
285}
286
287NPObject* NPObjectProxy::NP_Allocate(NPP npp, NPClass*)
288{
289    ASSERT_UNUSED(npp, !npp);
290
291    return new NPObjectProxy;
292}
293
294void NPObjectProxy::NP_Deallocate(NPObject* npObject)
295{
296    NPObjectProxy* npObjectProxy = toNPObjectProxy(npObject);
297    delete npObjectProxy;
298}
299
300bool NPObjectProxy::NP_HasMethod(NPObject* npObject, NPIdentifier methodName)
301{
302    return toNPObjectProxy(npObject)->hasMethod(methodName);
303}
304
305bool NPObjectProxy::NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
306{
307    return toNPObjectProxy(npObject)->invoke(methodName, arguments, argumentCount, result);
308}
309
310bool NPObjectProxy::NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
311{
312    return toNPObjectProxy(npObject)->invokeDefault(arguments, argumentCount, result);
313}
314
315bool NPObjectProxy::NP_HasProperty(NPObject* npObject, NPIdentifier propertyName)
316{
317    return toNPObjectProxy(npObject)->hasProperty(propertyName);
318}
319
320bool NPObjectProxy::NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
321{
322    return toNPObjectProxy(npObject)->getProperty(propertyName, result);
323}
324
325bool NPObjectProxy::NP_SetProperty(NPObject* npObject, NPIdentifier propertyName, const NPVariant* value)
326{
327    return toNPObjectProxy(npObject)->setProperty(propertyName, value);
328}
329
330bool NPObjectProxy::NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName)
331{
332    return toNPObjectProxy(npObject)->removeProperty(propertyName);
333}
334
335bool NPObjectProxy::NP_Enumerate(NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount)
336{
337    return toNPObjectProxy(npObject)->enumerate(identifiers, identifierCount);
338}
339
340bool NPObjectProxy::NP_Construct(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
341{
342    return toNPObjectProxy(npObject)->construct(arguments, argumentCount, result);
343}
344
345} // namespace WebKit
346
347#endif // ENABLE(PLUGIN_PROCESS)
348