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 "PluginTest.h"
27
28#include "PluginObject.h"
29#include <assert.h>
30#include <string.h>
31#include <wtf/Platform.h>
32#include <wtf/ExportMacros.h>
33#include <wtf/Seconds.h>
34
35#if defined(XP_UNIX) || defined(ANDROID)
36#include <unistd.h>
37#endif
38
39using namespace std;
40extern NPNetscapeFuncs *browser;
41
42static void (*shutdownFunction)();
43
44PluginTest* PluginTest::create(NPP npp, const string& identifier)
45{
46 if (identifier.empty())
47 return new PluginTest(npp, identifier);
48
49 CreateTestFunction createTestFunction = createTestFunctions()[identifier];
50 if (createTestFunction)
51 return createTestFunction(npp, identifier);
52
53 return 0;
54}
55
56PluginTest::PluginTest(NPP npp, const string& identifier)
57 : m_npp(npp)
58 , m_identifier(identifier)
59{
60 // Reset the shutdown function.
61 shutdownFunction = 0;
62}
63
64PluginTest::~PluginTest()
65{
66}
67
68void PluginTest::NP_Shutdown()
69{
70 if (shutdownFunction)
71 shutdownFunction();
72}
73
74void PluginTest::registerNPShutdownFunction(void (*func)())
75{
76 assert(!shutdownFunction);
77 shutdownFunction = func;
78}
79
80void PluginTest::indicateTestFailure()
81{
82 // This should really be an assert, but there's no way for the test framework
83 // to know that the plug-in process crashed, so we'll just sleep for a while
84 // to ensure that the test times out.
85 sleep(1000_s);
86}
87
88NPError PluginTest::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved)
89{
90 return NPERR_NO_ERROR;
91}
92
93NPError PluginTest::NPP_Destroy(NPSavedData**)
94{
95 return NPERR_NO_ERROR;
96}
97
98NPError PluginTest::NPP_SetWindow(NPWindow*)
99{
100 return NPERR_NO_ERROR;
101}
102
103NPError PluginTest::NPP_NewStream(NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
104{
105 return NPERR_NO_ERROR;
106}
107
108NPError PluginTest::NPP_DestroyStream(NPStream *stream, NPReason reason)
109{
110 return NPERR_NO_ERROR;
111}
112
113int32_t PluginTest::NPP_WriteReady(NPStream*)
114{
115 return 4096;
116}
117
118int32_t PluginTest::NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer)
119{
120 return len;
121}
122
123int16_t PluginTest::NPP_HandleEvent(void*)
124{
125 return 0;
126}
127
128bool PluginTest::NPP_URLNotify(const char* url, NPReason, void* notifyData)
129{
130 // FIXME: Port the code from NPP_URLNotify in main.cpp over to always using
131 // PluginTest, so we don't have to use a return value to indicate whether the "default" NPP_URLNotify implementation should be invoked.
132 return false;
133}
134
135void PluginTest::NPP_URLRedirectNotify(const char*, int32_t, void* notifyData)
136{
137 NPN_URLRedirectResponse(notifyData, true);
138}
139
140NPError PluginTest::NPP_GetValue(NPPVariable variable, void *value)
141{
142 // We don't know anything about plug-in values so just return NPERR_GENERIC_ERROR.
143 return NPERR_GENERIC_ERROR;
144}
145
146NPError PluginTest::NPP_SetValue(NPNVariable, void *value)
147{
148 return NPERR_GENERIC_ERROR;
149}
150
151// NPN functions.
152
153NPError PluginTest::NPN_GetURL(const char* url, const char* target)
154{
155 return browser->geturl(m_npp, url, target);
156}
157
158NPError PluginTest::NPN_GetURLNotify(const char *url, const char *target, void *notifyData)
159{
160 return browser->geturlnotify(m_npp, url, target, notifyData);
161}
162
163NPError PluginTest::NPN_PostURLNotify(const char *url, const char *target, uint32_t len, const char* buf, NPBool file, void *notifyData)
164{
165 return browser->posturlnotify(m_npp, url, target, len, buf, file, notifyData);
166}
167
168NPError PluginTest::NPN_GetValue(NPNVariable variable, void* value)
169{
170 return browser->getvalue(m_npp, variable, value);
171}
172
173void PluginTest::NPN_InvalidateRect(NPRect* invalidRect)
174{
175 browser->invalidaterect(m_npp, invalidRect);
176}
177
178bool PluginTest::NPN_Invoke(NPObject *npobj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result)
179{
180 return browser->invoke(m_npp, npobj, methodName, args, argCount, result);
181}
182
183void* PluginTest::NPN_MemAlloc(uint32_t size)
184{
185 return browser->memalloc(size);
186}
187
188// NPRuntime NPN functions.
189
190NPIdentifier PluginTest::NPN_GetStringIdentifier(const NPUTF8 *name)
191{
192 return browser->getstringidentifier(name);
193}
194
195NPIdentifier PluginTest::NPN_GetIntIdentifier(int32_t intid)
196{
197 return browser->getintidentifier(intid);
198}
199
200bool PluginTest::NPN_IdentifierIsString(NPIdentifier npIdentifier)
201{
202 return browser->identifierisstring(npIdentifier);
203}
204
205NPUTF8* PluginTest::NPN_UTF8FromIdentifier(NPIdentifier npIdentifier)
206{
207 return browser->utf8fromidentifier(npIdentifier);
208}
209
210int32_t PluginTest::NPN_IntFromIdentifier(NPIdentifier npIdentifier)
211{
212 return browser->intfromidentifier(npIdentifier);
213}
214
215NPObject* PluginTest::NPN_CreateObject(NPClass* npClass)
216{
217 return browser->createobject(m_npp, npClass);
218}
219
220NPObject* PluginTest::NPN_RetainObject(NPObject* npObject)
221{
222 return browser->retainobject(npObject);
223}
224
225void PluginTest::NPN_ReleaseObject(NPObject* npObject)
226{
227 browser->releaseobject(npObject);
228}
229
230bool PluginTest::NPN_RemoveProperty(NPObject* npObject, NPIdentifier propertyName)
231{
232 return browser->removeproperty(m_npp, npObject, propertyName);
233}
234
235void PluginTest::NPN_ReleaseVariantValue(NPVariant* variant)
236{
237 browser->releasevariantvalue(variant);
238}
239
240void PluginTest::NPN_URLRedirectResponse(void* notifyData, NPBool allow)
241{
242 browser->urlredirectresponse(m_npp, notifyData, allow);
243}
244
245#ifdef XP_MACOSX
246bool PluginTest::NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
247{
248 return browser->convertpoint(m_npp, sourceX, sourceY, sourceSpace, destX, destY, destSpace);
249}
250#endif
251
252bool PluginTest::executeScript(const NPString* script, NPVariant* result)
253{
254 NPObject* windowScriptObject;
255 browser->getvalue(m_npp, NPNVWindowNPObject, &windowScriptObject);
256
257 return browser->evaluate(m_npp, windowScriptObject, const_cast<NPString*>(script), result);
258}
259
260void PluginTest::executeScript(const char* script)
261{
262 NPString npScript;
263 npScript.UTF8Characters = script;
264 npScript.UTF8Length = strlen(script);
265
266 NPVariant browserResult;
267 executeScript(&npScript, &browserResult);
268 browser->releasevariantvalue(&browserResult);
269}
270
271void PluginTest::log(const char* format, ...)
272{
273 va_list args;
274 va_start(args, format);
275 pluginLogWithArguments(m_npp, format, args);
276 va_end(args);
277}
278
279NPNetscapeFuncs* PluginTest::netscapeFuncs()
280{
281 return browser;
282}
283
284void PluginTest::waitUntilDone()
285{
286 executeScript("testRunner.waitUntilDone()");
287}
288
289void PluginTest::notifyDone()
290{
291 executeScript("testRunner.notifyDone()");
292}
293
294void PluginTest::registerCreateTestFunction(const string& identifier, CreateTestFunction createTestFunction)
295{
296 assert(!createTestFunctions().count(identifier));
297
298 createTestFunctions()[identifier] = createTestFunction;
299}
300
301std::map<std::string, PluginTest::CreateTestFunction>& PluginTest::createTestFunctions()
302{
303 static std::map<std::string, CreateTestFunction> testFunctions;
304
305 return testFunctions;
306}
307