Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / shell / tools / plugin / PluginObject.cpp
bloba3c723fd85f6e5753a041bc924e25c13fff932ba
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /*
6 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
7 * Copyright (C) 2009 Holger Hans Peter Freyther
8 * Copyright (C) 2010 Collabora Ltd.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "PluginObject.h"
34 #include "PluginTest.h"
35 #include "content/shell/tools/plugin/test_object.h"
36 #include "base/strings/string_util.h"
37 #include <assert.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
42 // Helper function which takes in the plugin window object for logging to the
43 // console object.
44 static void pluginLogWithWindowObject(NPObject* windowObject,
45 NPP instance,
46 const char* message) {
47 NPVariant consoleVariant;
48 if (!browser->getproperty(instance,
49 windowObject,
50 browser->getstringidentifier("console"),
51 &consoleVariant)) {
52 fprintf(stderr,
53 "Failed to retrieve console object while logging: %s\n",
54 message);
55 return;
58 NPObject* consoleObject = NPVARIANT_TO_OBJECT(consoleVariant);
60 NPVariant messageVariant;
61 STRINGZ_TO_NPVARIANT(message, messageVariant);
63 NPVariant result;
64 if (!browser->invoke(instance,
65 consoleObject,
66 browser->getstringidentifier("log"),
67 &messageVariant,
69 &result)) {
70 fprintf(
71 stderr, "Failed to invoke console.log while logging: %s\n", message);
72 browser->releaseobject(consoleObject);
73 return;
76 browser->releasevariantvalue(&result);
77 browser->releaseobject(consoleObject);
80 void pluginLogWithArguments(NPP instance, const char* format, va_list args) {
81 const size_t messageBufferSize = 2048;
82 char message[messageBufferSize] = "PLUGIN: ";
83 int messageLength = sizeof("PLUGIN: ") - 1;
84 messageLength += vsnprintf(message + messageLength,
85 messageBufferSize - 1 - messageLength,
86 format,
87 args);
88 message[messageLength] = '\0';
90 NPObject* windowObject = 0;
91 NPError error =
92 browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
93 if (error != NPERR_NO_ERROR) {
94 fprintf(stderr,
95 "Failed to retrieve window object while logging: %s\n",
96 message);
97 return;
100 pluginLogWithWindowObject(windowObject, instance, message);
101 browser->releaseobject(windowObject);
104 // Helper function to log to the console object.
105 void pluginLog(NPP instance, const char* format, ...) {
106 va_list args;
107 va_start(args, format);
108 pluginLogWithArguments(instance, format, args);
109 va_end(args);
112 static void pluginInvalidate(NPObject*);
113 static bool pluginHasProperty(NPObject*, NPIdentifier name);
114 static bool pluginHasMethod(NPObject*, NPIdentifier name);
115 static bool pluginGetProperty(NPObject*, NPIdentifier name, NPVariant*);
116 static bool pluginSetProperty(NPObject*, NPIdentifier name, const NPVariant*);
117 static bool pluginInvoke(NPObject*,
118 NPIdentifier name,
119 const NPVariant* args,
120 uint32_t argCount,
121 NPVariant* result);
122 static NPObject* pluginAllocate(NPP npp, NPClass*);
123 static void pluginDeallocate(NPObject*);
125 NPNetscapeFuncs* browser;
126 NPPluginFuncs* pluginFunctions;
128 static NPClass pluginClass_ = {
129 NP_CLASS_STRUCT_VERSION, pluginAllocate, pluginDeallocate,
130 pluginInvalidate, pluginHasMethod, pluginInvoke,
131 0, // NPClass::invokeDefault,
132 pluginHasProperty, pluginGetProperty, pluginSetProperty,
133 0, // NPClass::removeProperty
134 0, // NPClass::enumerate
135 0, // NPClass::construct
138 NPClass* createPluginClass(void) {
139 NPClass* pluginClass = new NPClass;
140 *pluginClass = pluginClass_;
141 return pluginClass;
144 static bool identifiersInitialized = false;
146 enum {
147 ID_PROPERTY_PROPERTY = 0,
148 ID_PROPERTY_EVENT_LOGGING,
149 ID_PROPERTY_HAS_STREAM,
150 ID_PROPERTY_TEST_OBJECT,
151 ID_PROPERTY_LOG_DESTROY,
152 ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM,
153 ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE,
154 ID_PROPERTY_THROW_EXCEPTION_PROPERTY,
155 ID_LAST_SET_WINDOW_ARGUMENTS,
156 ID_PROPERTY_WINDOWED_PLUGIN,
157 ID_PROPERTY_TEST_OBJECT_COUNT,
158 ID_PROPERTY_DELETE_IN_GET_PROPERTY,
159 ID_PROPERTY_DELETE_IN_HAS_PROPERTY_RETURN_TRUE,
160 ID_PROPERTY_DELETE_IN_SET_PROPERTY,
161 NUM_PROPERTY_IDENTIFIERS
164 static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
165 static const NPUTF8* pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
166 "property", "eventLoggingEnabled",
167 "hasStream", "testObject",
168 "logDestroy", "returnErrorFromNewStream",
169 "returnNegativeOneFromWrite", "testThrowExceptionProperty",
170 "lastSetWindowArguments", "windowedPlugin",
171 "testObjectCount", "deletePluginInGetProperty",
172 "deletePluginInHasPropertyReturnTrue", "deletePluginInSetProperty"};
174 enum {
175 ID_TEST_CALLBACK_METHOD = 0,
176 ID_TEST_CALLBACK_METHOD_RETURN,
177 ID_TEST_GETURL,
178 ID_TEST_DOM_ACCESS,
179 ID_TEST_GET_URL_NOTIFY,
180 ID_TEST_INVOKE_DEFAULT,
181 ID_DESTROY_STREAM,
182 ID_TEST_ENUMERATE,
183 ID_TEST_GETINTIDENTIFIER,
184 ID_TEST_GET_PROPERTY,
185 ID_TEST_HAS_PROPERTY,
186 ID_TEST_HAS_METHOD,
187 ID_TEST_EVALUATE,
188 ID_TEST_GET_PROPERTY_RETURN_VALUE,
189 ID_TEST_IDENTIFIER_TO_STRING,
190 ID_TEST_IDENTIFIER_TO_INT,
191 ID_TEST_PASS_TEST_OBJECT,
192 ID_TEST_POSTURL_FILE,
193 ID_TEST_CONSTRUCT,
194 ID_TEST_THROW_EXCEPTION_METHOD,
195 ID_TEST_FAIL_METHOD,
196 ID_TEST_CLONE_OBJECT,
197 ID_TEST_SCRIPT_OBJECT_INVOKE,
198 ID_TEST_CREATE_TEST_OBJECT,
199 ID_DESTROY_NULL_STREAM,
200 ID_TEST_RELOAD_PLUGINS_NO_PAGES,
201 ID_TEST_RELOAD_PLUGINS_AND_PAGES,
202 ID_TEST_GET_BROWSER_PROPERTY,
203 ID_TEST_SET_BROWSER_PROPERTY,
204 ID_REMEMBER,
205 ID_GET_REMEMBERED_OBJECT,
206 ID_GET_AND_FORGET_REMEMBERED_OBJECT,
207 ID_REF_COUNT,
208 ID_SET_STATUS,
209 ID_RESIZE_TO,
210 ID_NORMALIZE,
211 ID_INVALIDATE_RECT,
212 ID_OBJECTS_ARE_SAME,
213 ID_TEST_DELETE_WITHIN_INVOKE,
214 NUM_METHOD_IDENTIFIERS
217 static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
218 static const NPUTF8* pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
219 "testCallback", "testCallbackReturn",
220 "getURL", "testDOMAccess",
221 "getURLNotify", "testInvokeDefault",
222 "destroyStream", "testEnumerate",
223 "testGetIntIdentifier", "testGetProperty",
224 "testHasProperty", "testHasMethod",
225 "testEvaluate", "testGetPropertyReturnValue",
226 "testIdentifierToString", "testIdentifierToInt",
227 "testPassTestObject", "testPostURLFile",
228 "testConstruct", "testThrowException",
229 "testFail", "testCloneObject",
230 "testScriptObjectInvoke", "testCreateTestObject",
231 "destroyNullStream", "reloadPluginsNoPages",
232 "reloadPluginsAndPages", "testGetBrowserProperty",
233 "testSetBrowserProperty", "remember",
234 "getRememberedObject", "getAndForgetRememberedObject",
235 "refCount", "setStatus",
236 "resizeTo", "normalize",
237 "invalidateRect", "objectsAreSame",
238 "testDeleteWithinInvoke"};
240 static NPUTF8* createCStringFromNPVariant(const NPVariant* variant) {
241 size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
242 NPUTF8* result = (NPUTF8*)malloc(length + 1);
243 memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
244 result[length] = '\0';
245 return result;
248 static void initializeIdentifiers(void) {
249 browser->getstringidentifiers(pluginPropertyIdentifierNames,
250 NUM_PROPERTY_IDENTIFIERS,
251 pluginPropertyIdentifiers);
252 browser->getstringidentifiers(pluginMethodIdentifierNames,
253 NUM_METHOD_IDENTIFIERS,
254 pluginMethodIdentifiers);
257 static bool callDeletePlugin(NPObject* obj,
258 NPIdentifier name,
259 NPIdentifier identifierToMatch) {
260 if (name != identifierToMatch)
261 return false;
263 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
264 NPObject* windowScriptObject;
265 browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);
267 NPIdentifier callbackIdentifier =
268 browser->getstringidentifier("deletePlugin");
269 NPVariant browserResult;
270 if (browser->invoke(plugin->npp,
271 windowScriptObject,
272 callbackIdentifier,
275 &browserResult))
276 browser->releasevariantvalue(&browserResult);
277 return true;
280 static bool pluginHasProperty(NPObject* obj, NPIdentifier name) {
281 if (callDeletePlugin(
282 obj,
283 name,
284 browser->getstringidentifier("deletePluginInHasPropertyReturnFalse")))
285 return false;
287 callDeletePlugin(obj,
288 name,
289 pluginPropertyIdentifiers
290 [ID_PROPERTY_DELETE_IN_HAS_PROPERTY_RETURN_TRUE]);
292 for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
293 if (name == pluginPropertyIdentifiers[i])
294 return true;
295 return false;
298 static bool pluginHasMethod(NPObject* obj, NPIdentifier name) {
299 if (callDeletePlugin(
300 obj, name, browser->getstringidentifier("deletePluginInHasMethod")))
301 return true;
303 for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
304 if (name == pluginMethodIdentifiers[i])
305 return true;
306 return false;
309 static bool pluginGetProperty(NPObject* obj,
310 NPIdentifier name,
311 NPVariant* result) {
312 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
313 if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
314 static const char* originalString = "property";
315 char* buf =
316 static_cast<char*>(browser->memalloc(strlen(originalString) + 1));
317 strcpy(buf, originalString);
318 STRINGZ_TO_NPVARIANT(buf, *result);
319 return true;
321 if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
322 BOOLEAN_TO_NPVARIANT(plugin->eventLogging, *result);
323 return true;
325 if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
326 BOOLEAN_TO_NPVARIANT(plugin->logDestroy, *result);
327 return true;
329 if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
330 BOOLEAN_TO_NPVARIANT(plugin->stream, *result);
331 return true;
333 if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
334 NPObject* testObject = plugin->testObject;
335 browser->retainobject(testObject);
336 OBJECT_TO_NPVARIANT(testObject, *result);
337 return true;
339 if (name ==
340 pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
341 BOOLEAN_TO_NPVARIANT(plugin->returnErrorFromNewStream, *result);
342 return true;
344 if (name ==
345 pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
346 BOOLEAN_TO_NPVARIANT(plugin->returnNegativeOneFromWrite, *result);
347 return true;
349 if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
350 browser->setexception(obj,
351 "plugin object testThrowExceptionProperty SUCCESS");
352 return true;
354 if (name == pluginPropertyIdentifiers[ID_LAST_SET_WINDOW_ARGUMENTS]) {
355 char* buf = static_cast<char*>(browser->memalloc(256));
356 snprintf(
357 buf,
358 256,
359 "x: %d, y: %d, width: %u, height: %u, clipRect: (%u, %u, %u, %u)",
360 (int)plugin->lastWindow.x,
361 (int)plugin->lastWindow.y,
362 (unsigned)plugin->lastWindow.width,
363 (unsigned)plugin->lastWindow.height,
364 plugin->lastWindow.clipRect.left,
365 plugin->lastWindow.clipRect.top,
366 plugin->lastWindow.clipRect.right - plugin->lastWindow.clipRect.left,
367 plugin->lastWindow.clipRect.bottom - plugin->lastWindow.clipRect.top);
369 STRINGZ_TO_NPVARIANT(buf, *result);
370 return true;
372 if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT_COUNT]) {
373 INT32_TO_NPVARIANT(content::GetTestObjectCount(), *result);
374 return true;
377 if (name == pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_GET_PROPERTY]) {
378 browser->retainobject(obj);
379 callDeletePlugin(
380 obj,
381 name,
382 pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_GET_PROPERTY]);
383 NPObject* testObject = plugin->testObject;
384 browser->retainobject(testObject);
385 OBJECT_TO_NPVARIANT(testObject, *result);
386 browser->releaseobject(obj);
387 return true;
390 return false;
393 static bool pluginSetProperty(NPObject* obj,
394 NPIdentifier name,
395 const NPVariant* variant) {
396 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
397 if (callDeletePlugin(
398 obj,
399 name,
400 pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_SET_PROPERTY]))
401 return true;
403 if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
404 plugin->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
405 return true;
407 if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
408 plugin->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
409 return true;
411 if (name ==
412 pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
413 plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant);
414 return true;
416 if (name ==
417 pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
418 plugin->returnNegativeOneFromWrite = NPVARIANT_TO_BOOLEAN(*variant);
419 return true;
421 if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
422 browser->setexception(obj,
423 "plugin object testThrowExceptionProperty SUCCESS");
424 return true;
426 if (name == pluginPropertyIdentifiers[ID_PROPERTY_WINDOWED_PLUGIN]) {
427 browser->setvalue(plugin->npp,
428 NPPVpluginWindowBool,
429 (void*)NPVARIANT_TO_BOOLEAN(*variant));
430 return true;
433 return false;
436 static bool testDOMAccess(PluginObject* obj,
437 const NPVariant*,
438 uint32_t,
439 NPVariant* result) {
440 // Get plugin's DOM element
441 NPObject* elementObject;
442 if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) ==
443 NPERR_NO_ERROR) {
444 // Get style
445 NPVariant styleVariant;
446 NPIdentifier styleIdentifier = browser->getstringidentifier("style");
447 if (browser->getproperty(
448 obj->npp, elementObject, styleIdentifier, &styleVariant) &&
449 NPVARIANT_IS_OBJECT(styleVariant)) {
450 // Set style.border
451 NPIdentifier borderIdentifier = browser->getstringidentifier("border");
452 NPVariant borderVariant;
453 STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
454 browser->setproperty(obj->npp,
455 NPVARIANT_TO_OBJECT(styleVariant),
456 borderIdentifier,
457 &borderVariant);
458 browser->releasevariantvalue(&styleVariant);
461 browser->releaseobject(elementObject);
463 VOID_TO_NPVARIANT(*result);
464 return true;
467 static NPIdentifier stringVariantToIdentifier(NPVariant variant) {
468 assert(NPVARIANT_IS_STRING(variant));
469 NPUTF8* utf8String = createCStringFromNPVariant(&variant);
470 NPIdentifier identifier = browser->getstringidentifier(utf8String);
471 free(utf8String);
472 return identifier;
475 static NPIdentifier int32VariantToIdentifier(NPVariant variant) {
476 assert(NPVARIANT_IS_INT32(variant));
477 int32_t integer = NPVARIANT_TO_INT32(variant);
478 return browser->getintidentifier(integer);
481 static NPIdentifier doubleVariantToIdentifier(NPVariant variant) {
482 assert(NPVARIANT_IS_DOUBLE(variant));
483 double value = NPVARIANT_TO_DOUBLE(variant);
484 // Sadly there is no "getdoubleidentifier"
485 int32_t integer = static_cast<int32_t>(value);
486 return browser->getintidentifier(integer);
489 static NPIdentifier variantToIdentifier(NPVariant variant) {
490 if (NPVARIANT_IS_STRING(variant))
491 return stringVariantToIdentifier(variant);
492 if (NPVARIANT_IS_INT32(variant))
493 return int32VariantToIdentifier(variant);
494 if (NPVARIANT_IS_DOUBLE(variant))
495 return doubleVariantToIdentifier(variant);
496 return 0;
499 static bool testIdentifierToString(PluginObject*,
500 const NPVariant* args,
501 uint32_t argCount,
502 NPVariant* result) {
503 if (argCount != 1)
504 return true;
505 NPIdentifier identifier = variantToIdentifier(args[0]);
506 if (!identifier)
507 return true;
508 NPUTF8* utf8String = browser->utf8fromidentifier(identifier);
509 if (!utf8String)
510 return true;
511 STRINGZ_TO_NPVARIANT(utf8String, *result);
512 return true;
515 static bool testIdentifierToInt(PluginObject*,
516 const NPVariant* args,
517 uint32_t argCount,
518 NPVariant* result) {
519 if (argCount != 1)
520 return false;
521 NPIdentifier identifier = variantToIdentifier(args[0]);
522 if (!identifier)
523 return false;
524 int32_t integer = browser->intfromidentifier(identifier);
525 INT32_TO_NPVARIANT(integer, *result);
526 return true;
529 static bool testPassTestObject(PluginObject* obj,
530 const NPVariant* args,
531 uint32_t argCount,
532 NPVariant* result) {
533 if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]))
534 return false;
536 NPObject* windowScriptObject;
537 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
539 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
540 NPIdentifier callbackIdentifier =
541 browser->getstringidentifier(callbackString);
542 free(callbackString);
544 NPVariant browserResult;
545 browser->invoke(obj->npp,
546 windowScriptObject,
547 callbackIdentifier,
548 &args[1],
550 &browserResult);
551 browser->releasevariantvalue(&browserResult);
553 VOID_TO_NPVARIANT(*result);
554 return true;
557 static bool testCallback(PluginObject* obj,
558 const NPVariant* args,
559 uint32_t argCount,
560 NPVariant* result) {
561 if (!argCount || !NPVARIANT_IS_STRING(args[0]))
562 return false;
564 NPObject* windowScriptObject;
565 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
567 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
568 NPIdentifier callbackIdentifier =
569 browser->getstringidentifier(callbackString);
570 free(callbackString);
572 NPVariant browserResult;
573 if (browser->invoke(obj->npp,
574 windowScriptObject,
575 callbackIdentifier,
578 &browserResult))
579 browser->releasevariantvalue(&browserResult);
581 browser->releaseobject(windowScriptObject);
583 VOID_TO_NPVARIANT(*result);
584 return true;
587 static bool testCallbackReturn(PluginObject* obj,
588 const NPVariant* args,
589 uint32_t argCount,
590 NPVariant* result) {
591 if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
592 return false;
594 NPObject* windowScriptObject;
595 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
597 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
598 NPIdentifier callbackIdentifier =
599 browser->getstringidentifier(callbackString);
600 free(callbackString);
602 NPVariant callbackArgs[1];
603 OBJECT_TO_NPVARIANT(windowScriptObject, callbackArgs[0]);
605 NPVariant browserResult;
606 browser->invoke(obj->npp,
607 windowScriptObject,
608 callbackIdentifier,
609 callbackArgs,
611 &browserResult);
613 if (NPVARIANT_IS_OBJECT(browserResult))
614 OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(browserResult), *result);
615 else {
616 browser->releasevariantvalue(&browserResult);
617 VOID_TO_NPVARIANT(*result);
620 return true;
623 static bool getURL(PluginObject* obj,
624 const NPVariant* args,
625 uint32_t argCount,
626 NPVariant* result) {
627 if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) &&
628 NPVARIANT_IS_STRING(args[1])) {
629 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
630 NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
631 NPError npErr = browser->geturl(obj->npp, urlString, targetString);
632 free(urlString);
633 free(targetString);
635 INT32_TO_NPVARIANT(npErr, *result);
636 return true;
638 if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
639 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
640 NPError npErr = browser->geturl(obj->npp, urlString, 0);
641 free(urlString);
643 INT32_TO_NPVARIANT(npErr, *result);
644 return true;
646 return false;
649 static bool getURLNotify(PluginObject* obj,
650 const NPVariant* args,
651 uint32_t argCount,
652 NPVariant* result) {
653 if (argCount != 3 || !NPVARIANT_IS_STRING(args[0]) ||
654 (!NPVARIANT_IS_STRING(args[1]) && !NPVARIANT_IS_NULL(args[1])) ||
655 !NPVARIANT_IS_STRING(args[2]))
656 return false;
658 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
659 NPUTF8* targetString =
660 (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : 0);
661 NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
663 NPIdentifier callbackIdentifier =
664 browser->getstringidentifier(callbackString);
665 browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
667 free(urlString);
668 free(targetString);
669 free(callbackString);
671 VOID_TO_NPVARIANT(*result);
672 return true;
675 static bool testInvokeDefault(PluginObject* obj,
676 const NPVariant* args,
677 uint32_t argCount,
678 NPVariant* result) {
679 if (!NPVARIANT_IS_OBJECT(args[0]))
680 return false;
682 NPObject* callback = NPVARIANT_TO_OBJECT(args[0]);
684 NPVariant invokeArgs[1];
685 NPVariant browserResult;
687 STRINGZ_TO_NPVARIANT("test", invokeArgs[0]);
688 bool retval =
689 browser->invokeDefault(obj->npp, callback, invokeArgs, 1, &browserResult);
691 if (retval)
692 browser->releasevariantvalue(&browserResult);
694 BOOLEAN_TO_NPVARIANT(retval, *result);
695 return true;
698 static bool destroyStream(PluginObject* obj,
699 const NPVariant* args,
700 uint32_t argCount,
701 NPVariant* result) {
702 NPError npError =
703 browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
704 INT32_TO_NPVARIANT(npError, *result);
705 return true;
708 static bool destroyNullStream(PluginObject* obj,
709 const NPVariant* args,
710 uint32_t argCount,
711 NPVariant* result) {
712 NPError npError = browser->destroystream(obj->npp, 0, NPRES_USER_BREAK);
713 INT32_TO_NPVARIANT(npError, *result);
714 return true;
717 static bool testEnumerate(PluginObject* obj,
718 const NPVariant* args,
719 uint32_t argCount,
720 NPVariant* result) {
721 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
722 !NPVARIANT_IS_OBJECT(args[1]))
723 return false;
725 uint32_t count;
726 NPIdentifier* identifiers;
727 if (browser->enumerate(
728 obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
729 NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
730 NPIdentifier pushIdentifier = browser->getstringidentifier("push");
732 for (uint32_t i = 0; i < count; i++) {
733 NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);
735 if (!string)
736 continue;
738 NPVariant args[1];
739 STRINGZ_TO_NPVARIANT(string, args[0]);
740 NPVariant browserResult;
741 if (browser->invoke(
742 obj->npp, outArray, pushIdentifier, args, 1, &browserResult))
743 browser->releasevariantvalue(&browserResult);
744 browser->memfree(string);
747 browser->memfree(identifiers);
750 VOID_TO_NPVARIANT(*result);
751 return true;
754 static bool testGetIntIdentifier(PluginObject*,
755 const NPVariant* args,
756 uint32_t argCount,
757 NPVariant* result) {
758 if (argCount != 1 || !NPVARIANT_IS_DOUBLE(args[0]))
759 return false;
761 NPIdentifier identifier =
762 browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0]));
763 INT32_TO_NPVARIANT((int32_t)(long long)identifier, *result);
764 return true;
767 static bool testGetProperty(PluginObject* obj,
768 const NPVariant* args,
769 uint32_t argCount,
770 NPVariant* result) {
771 if (!argCount)
772 return false;
774 NPObject* object;
775 browser->getvalue(obj->npp, NPNVWindowNPObject, &object);
777 for (uint32_t i = 0; i < argCount; i++) {
778 assert(NPVARIANT_IS_STRING(args[i]));
779 NPUTF8* propertyString = createCStringFromNPVariant(&args[i]);
780 NPIdentifier propertyIdentifier =
781 browser->getstringidentifier(propertyString);
782 free(propertyString);
784 NPVariant variant;
785 bool retval =
786 browser->getproperty(obj->npp, object, propertyIdentifier, &variant);
787 browser->releaseobject(object);
789 if (!retval)
790 break;
792 if (i + 1 < argCount) {
793 assert(NPVARIANT_IS_OBJECT(variant));
794 object = NPVARIANT_TO_OBJECT(variant);
795 } else {
796 *result = variant;
797 return true;
801 VOID_TO_NPVARIANT(*result);
802 return false;
805 static bool testHasProperty(PluginObject* obj,
806 const NPVariant* args,
807 uint32_t argCount,
808 NPVariant* result) {
809 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
810 !NPVARIANT_IS_STRING(args[1]))
811 return false;
813 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
814 NPIdentifier propertyIdentifier =
815 browser->getstringidentifier(propertyString);
816 free(propertyString);
818 bool retval = browser->hasproperty(
819 obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier);
821 BOOLEAN_TO_NPVARIANT(retval, *result);
822 return true;
825 static bool testHasMethod(PluginObject* obj,
826 const NPVariant* args,
827 uint32_t argCount,
828 NPVariant* result) {
829 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
830 !NPVARIANT_IS_STRING(args[1]))
831 return false;
833 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
834 NPIdentifier propertyIdentifier =
835 browser->getstringidentifier(propertyString);
836 free(propertyString);
838 bool retval = browser->hasmethod(
839 obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier);
841 BOOLEAN_TO_NPVARIANT(retval, *result);
842 return true;
845 static bool testEvaluate(PluginObject* obj,
846 const NPVariant* args,
847 uint32_t argCount,
848 NPVariant* result) {
849 if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
850 return false;
851 NPObject* windowScriptObject;
852 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
854 NPString s = NPVARIANT_TO_STRING(args[0]);
856 bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result);
857 browser->releaseobject(windowScriptObject);
858 return retval;
861 static bool testGetPropertyReturnValue(PluginObject* obj,
862 const NPVariant* args,
863 uint32_t argCount,
864 NPVariant* result) {
865 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
866 !NPVARIANT_IS_STRING(args[1]))
867 return false;
869 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
870 NPIdentifier propertyIdentifier =
871 browser->getstringidentifier(propertyString);
872 free(propertyString);
874 NPVariant variant;
875 bool retval = browser->getproperty(
876 obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier, &variant);
877 if (retval)
878 browser->releasevariantvalue(&variant);
880 BOOLEAN_TO_NPVARIANT(retval, *result);
881 return true;
884 static char* toCString(const NPString& string) {
885 char* result = static_cast<char*>(malloc(string.UTF8Length + 1));
886 memcpy(result, string.UTF8Characters, string.UTF8Length);
887 result[string.UTF8Length] = '\0';
889 return result;
892 static bool testPostURLFile(PluginObject* obj,
893 const NPVariant* args,
894 uint32_t argCount,
895 NPVariant* result) {
896 if (argCount != 4 || !NPVARIANT_IS_STRING(args[0]) ||
897 !NPVARIANT_IS_STRING(args[1]) || !NPVARIANT_IS_STRING(args[2]) ||
898 !NPVARIANT_IS_STRING(args[3]))
899 return false;
901 NPString urlString = NPVARIANT_TO_STRING(args[0]);
902 char* url = toCString(urlString);
904 NPString targetString = NPVARIANT_TO_STRING(args[1]);
905 char* target = toCString(targetString);
907 NPString pathString = NPVARIANT_TO_STRING(args[2]);
908 char* path = toCString(pathString);
910 NPString contentsString = NPVARIANT_TO_STRING(args[3]);
912 FILE* tempFile = fopen(path, "w");
913 if (!tempFile)
914 return false;
916 size_t written = fwrite(
917 contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile);
918 fclose(tempFile);
919 if (!written)
920 return false;
922 NPError error = browser->posturl(
923 obj->npp, url, target, pathString.UTF8Length, path, true);
925 free(path);
926 free(target);
927 free(url);
929 BOOLEAN_TO_NPVARIANT(error == NPERR_NO_ERROR, *result);
930 return true;
933 static bool testConstruct(PluginObject* obj,
934 const NPVariant* args,
935 uint32_t argCount,
936 NPVariant* result) {
937 if (!argCount || !NPVARIANT_IS_OBJECT(args[0]))
938 return false;
940 return browser->construct(
941 obj->npp, NPVARIANT_TO_OBJECT(args[0]), args + 1, argCount - 1, result);
944 // Invoke a script callback to get a script NPObject. Then call a method on the
945 // script NPObject passing it a freshly created NPObject.
946 static bool testScriptObjectInvoke(PluginObject* obj,
947 const NPVariant* args,
948 uint32_t argCount,
949 NPVariant* result) {
950 if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]) ||
951 !NPVARIANT_IS_STRING(args[1]))
952 return false;
953 NPObject* windowScriptObject;
954 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
956 // Arg1 is the name of the callback
957 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
958 NPIdentifier callbackIdentifier =
959 browser->getstringidentifier(callbackString);
960 free(callbackString);
962 // Invoke a callback that returns a script object
963 NPVariant object_result;
964 browser->invoke(obj->npp,
965 windowScriptObject,
966 callbackIdentifier,
967 &args[1],
969 &object_result);
971 // Script object returned
972 if (!NPVARIANT_IS_OBJECT(object_result)) {
973 browser->releasevariantvalue(&object_result);
974 return false;
976 NPObject* script_object = NPVARIANT_TO_OBJECT(object_result);
978 // Arg2 is the name of the method to be called on the script object
979 NPUTF8* object_method_string = createCStringFromNPVariant(&args[1]);
980 NPIdentifier object_method =
981 browser->getstringidentifier(object_method_string);
982 free(object_method_string);
984 // Create a fresh NPObject to be passed as an argument
985 NPObject* object_arg = browser->createobject(obj->npp, obj->header._class);
987 NPVariant invoke_args[1];
988 OBJECT_TO_NPVARIANT(object_arg, invoke_args[0]);
990 // Invoke the script method
991 NPVariant object_method_result;
992 browser->invoke(obj->npp,
993 script_object,
994 object_method,
995 invoke_args,
997 &object_method_result);
999 browser->releasevariantvalue(&object_result);
1000 VOID_TO_NPVARIANT(*result);
1001 if (NPVARIANT_IS_OBJECT(object_method_result)) {
1002 // Now return the callbacks return value back to our caller.
1003 // BUG 897451: This should be the same as the
1004 // windowScriptObject, but its not (in Chrome) - or at least, it
1005 // has a different refcount. This means Chrome will delete the
1006 // object before returning it and the calling JS gets a garbage
1007 // value. Firefox handles it fine.
1008 OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(object_method_result), *result);
1009 } else {
1010 browser->releasevariantvalue(&object_method_result);
1011 VOID_TO_NPVARIANT(*result);
1014 browser->releaseobject(object_arg);
1016 return true;
1019 // Helper function to notify the layout test controller that the test completed.
1020 void notifyTestCompletion(NPP npp, NPObject* object) {
1021 NPVariant result;
1022 NPString script;
1023 script.UTF8Characters = "javascript:window.testRunner.notifyDone();";
1024 script.UTF8Length = strlen("javascript:window.testRunner.notifyDone();");
1025 browser->evaluate(npp, object, &script, &result);
1026 browser->releasevariantvalue(&result);
1029 bool testDocumentOpen(NPP npp) {
1030 NPIdentifier documentId = browser->getstringidentifier("document");
1031 NPIdentifier openId = browser->getstringidentifier("open");
1033 NPObject* windowObject = 0;
1034 browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
1035 if (!windowObject)
1036 return false;
1038 NPVariant docVariant;
1039 browser->getproperty(npp, windowObject, documentId, &docVariant);
1040 if (docVariant.type != NPVariantType_Object) {
1041 browser->releaseobject(windowObject);
1042 return false;
1045 NPObject* documentObject = NPVARIANT_TO_OBJECT(docVariant);
1047 NPVariant openArgs[2];
1048 STRINGZ_TO_NPVARIANT("text/html", openArgs[0]);
1049 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);
1051 NPVariant result;
1052 if (!browser->invoke(npp, documentObject, openId, openArgs, 2, &result)) {
1053 browser->releaseobject(windowObject);
1054 browser->releaseobject(documentObject);
1055 return false;
1058 browser->releaseobject(documentObject);
1060 if (result.type != NPVariantType_Object) {
1061 browser->releaseobject(windowObject);
1062 browser->releasevariantvalue(&result);
1063 return false;
1066 pluginLogWithWindowObject(windowObject, npp, "PLUGIN: DOCUMENT OPEN SUCCESS");
1067 notifyTestCompletion(npp, result.value.objectValue);
1068 browser->releaseobject(result.value.objectValue);
1069 browser->releaseobject(windowObject);
1070 return true;
1073 bool testWindowOpen(NPP npp) {
1074 NPIdentifier openId = browser->getstringidentifier("open");
1076 NPObject* windowObject = 0;
1077 browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
1078 if (!windowObject)
1079 return false;
1081 NPVariant openArgs[2];
1082 STRINGZ_TO_NPVARIANT("about:blank", openArgs[0]);
1083 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);
1085 NPVariant result;
1086 if (!browser->invoke(npp, windowObject, openId, openArgs, 2, &result)) {
1087 browser->releaseobject(windowObject);
1088 return false;
1091 if (result.type != NPVariantType_Object) {
1092 browser->releaseobject(windowObject);
1093 browser->releasevariantvalue(&result);
1094 return false;
1097 pluginLogWithWindowObject(windowObject, npp, "PLUGIN: WINDOW OPEN SUCCESS");
1098 notifyTestCompletion(npp, result.value.objectValue);
1099 browser->releaseobject(result.value.objectValue);
1100 browser->releaseobject(windowObject);
1101 return true;
1104 static bool testSetStatus(PluginObject* obj,
1105 const NPVariant* args,
1106 uint32_t argCount,
1107 NPVariant* result) {
1108 char* message = 0;
1109 if (argCount && NPVARIANT_IS_STRING(args[0])) {
1110 NPString statusString = NPVARIANT_TO_STRING(args[0]);
1111 message = toCString(statusString);
1114 browser->status(obj->npp, message);
1116 free(message);
1117 return true;
1120 static bool testResizeTo(PluginObject* obj,
1121 const NPVariant* args,
1122 uint32_t argCount,
1123 NPVariant* result) {
1124 VOID_TO_NPVARIANT(*result);
1126 NPObject* windowObject;
1127 if (NPERR_NO_ERROR !=
1128 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
1129 return false;
1131 NPVariant callResult;
1132 if (browser->invoke(obj->npp,
1133 windowObject,
1134 browser->getstringidentifier("resizePlugin"),
1135 args,
1136 argCount,
1137 &callResult))
1138 browser->releasevariantvalue(&callResult);
1140 // Force layout.
1141 if (browser->getproperty(obj->npp,
1142 windowObject,
1143 browser->getstringidentifier("pageYOffset"),
1144 &callResult))
1145 browser->releasevariantvalue(&callResult);
1147 return true;
1150 static bool normalizeOverride(PluginObject* obj,
1151 const NPVariant* args,
1152 uint32_t argCount,
1153 NPVariant* result) {
1154 VOID_TO_NPVARIANT(*result);
1156 NPObject* windowObject;
1157 if (NPERR_NO_ERROR !=
1158 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
1159 return false;
1161 NPVariant callResult;
1162 if (browser->invoke(obj->npp,
1163 windowObject,
1164 browser->getstringidentifier("pluginCallback"),
1165 args,
1166 argCount,
1167 &callResult))
1168 browser->releasevariantvalue(&callResult);
1170 return true;
1173 static bool invalidateRect(PluginObject* obj,
1174 const NPVariant* args,
1175 uint32_t argCount,
1176 NPVariant* result) {
1177 if (argCount != 4)
1178 return false;
1180 NPRect rect;
1181 rect.left = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[0]));
1182 rect.top = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[1]));
1183 rect.right = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[2]));
1184 rect.bottom = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[3]));
1186 browser->invalidaterect(obj->npp, &rect);
1187 return true;
1190 static bool objectsAreSame(PluginObject* obj,
1191 const NPVariant* args,
1192 uint32_t argCount,
1193 NPVariant* result) {
1194 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
1195 !NPVARIANT_IS_OBJECT(args[1]))
1196 return false;
1198 BOOLEAN_TO_NPVARIANT(
1199 NPVARIANT_TO_OBJECT(args[0]) == NPVARIANT_TO_OBJECT(args[1]), *result);
1200 return true;
1203 static bool pluginInvoke(NPObject* header,
1204 NPIdentifier name,
1205 const NPVariant* args,
1206 uint32_t argCount,
1207 NPVariant* result) {
1208 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1209 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD])
1210 return testCallback(plugin, args, argCount, result);
1211 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD_RETURN])
1212 return testCallbackReturn(plugin, args, argCount, result);
1213 if (name == pluginMethodIdentifiers[ID_TEST_GETURL])
1214 return getURL(plugin, args, argCount, result);
1215 if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS])
1216 return testDOMAccess(plugin, args, argCount, result);
1217 if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY])
1218 return getURLNotify(plugin, args, argCount, result);
1219 if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT])
1220 return testInvokeDefault(plugin, args, argCount, result);
1221 if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE])
1222 return testEnumerate(plugin, args, argCount, result);
1223 if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM])
1224 return destroyStream(plugin, args, argCount, result);
1225 if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER])
1226 return testGetIntIdentifier(plugin, args, argCount, result);
1227 if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE])
1228 return testEvaluate(plugin, args, argCount, result);
1229 if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY])
1230 return testGetProperty(plugin, args, argCount, result);
1231 if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE])
1232 return testGetPropertyReturnValue(plugin, args, argCount, result);
1233 if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY])
1234 return testHasProperty(plugin, args, argCount, result);
1235 if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD])
1236 return testHasMethod(plugin, args, argCount, result);
1237 if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING])
1238 return testIdentifierToString(plugin, args, argCount, result);
1239 if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT])
1240 return testIdentifierToInt(plugin, args, argCount, result);
1241 if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT])
1242 return testPassTestObject(plugin, args, argCount, result);
1243 if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE])
1244 return testPostURLFile(plugin, args, argCount, result);
1245 if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT])
1246 return testConstruct(plugin, args, argCount, result);
1247 if (name == pluginMethodIdentifiers[ID_TEST_SCRIPT_OBJECT_INVOKE])
1248 return testScriptObjectInvoke(plugin, args, argCount, result);
1249 if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) {
1250 browser->setexception(header, "plugin object testThrowException SUCCESS");
1251 return true;
1253 if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) {
1254 NPObject* windowScriptObject;
1255 browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);
1256 browser->invoke(
1257 plugin->npp, windowScriptObject, name, args, argCount, result);
1258 return false;
1260 if (name == pluginMethodIdentifiers[ID_TEST_CLONE_OBJECT]) {
1261 NPObject* new_object =
1262 browser->createobject(plugin->npp, plugin->header._class);
1263 assert(new_object->referenceCount == 1);
1264 OBJECT_TO_NPVARIANT(new_object, *result);
1265 return true;
1267 if (name == pluginMethodIdentifiers[ID_TEST_CREATE_TEST_OBJECT]) {
1268 NPObject* testObject =
1269 browser->createobject(plugin->npp, content::GetTestClass());
1270 assert(testObject->referenceCount == 1);
1271 OBJECT_TO_NPVARIANT(testObject, *result);
1272 return true;
1274 if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM])
1275 return destroyNullStream(plugin, args, argCount, result);
1276 if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) {
1277 browser->reloadplugins(false);
1278 return true;
1280 if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) {
1281 browser->reloadplugins(true);
1282 return true;
1284 if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) {
1285 browser->getproperty(plugin->npp,
1286 NPVARIANT_TO_OBJECT(args[0]),
1287 stringVariantToIdentifier(args[1]),
1288 result);
1289 return true;
1291 if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) {
1292 browser->setproperty(plugin->npp,
1293 NPVARIANT_TO_OBJECT(args[0]),
1294 stringVariantToIdentifier(args[1]),
1295 &args[2]);
1296 return true;
1298 if (name == pluginMethodIdentifiers[ID_REMEMBER]) {
1299 if (plugin->rememberedObject)
1300 browser->releaseobject(plugin->rememberedObject);
1301 plugin->rememberedObject = NPVARIANT_TO_OBJECT(args[0]);
1302 browser->retainobject(plugin->rememberedObject);
1303 VOID_TO_NPVARIANT(*result);
1304 return true;
1306 if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) {
1307 assert(plugin->rememberedObject);
1308 browser->retainobject(plugin->rememberedObject);
1309 OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
1310 return true;
1312 if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) {
1313 assert(plugin->rememberedObject);
1314 OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
1315 plugin->rememberedObject = 0;
1316 return true;
1318 if (name == pluginMethodIdentifiers[ID_REF_COUNT]) {
1319 uint32_t refCount = NPVARIANT_TO_OBJECT(args[0])->referenceCount;
1320 INT32_TO_NPVARIANT(refCount, *result);
1321 return true;
1323 if (name == pluginMethodIdentifiers[ID_SET_STATUS])
1324 return testSetStatus(plugin, args, argCount, result);
1325 if (name == pluginMethodIdentifiers[ID_RESIZE_TO])
1326 return testResizeTo(plugin, args, argCount, result);
1327 if (name == pluginMethodIdentifiers[ID_NORMALIZE])
1328 return normalizeOverride(plugin, args, argCount, result);
1329 if (name == pluginMethodIdentifiers[ID_INVALIDATE_RECT])
1330 return invalidateRect(plugin, args, argCount, result);
1331 if (name == pluginMethodIdentifiers[ID_OBJECTS_ARE_SAME])
1332 return objectsAreSame(plugin, args, argCount, result);
1333 if (name == pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]) {
1334 NPObject* newObject =
1335 browser->createobject(plugin->npp, plugin->header._class);
1336 OBJECT_TO_NPVARIANT(newObject, *result);
1337 callDeletePlugin(
1338 header, name, pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]);
1339 return true;
1341 return false;
1344 static void pluginInvalidate(NPObject* header) {
1345 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1346 plugin->testObject = 0;
1347 plugin->rememberedObject = 0;
1350 static NPObject* pluginAllocate(NPP npp, NPClass* theClass) {
1351 PluginObject* newInstance = (PluginObject*)malloc(sizeof(PluginObject));
1353 if (!identifiersInitialized) {
1354 identifiersInitialized = true;
1355 initializeIdentifiers();
1358 newInstance->pluginTest = 0;
1359 newInstance->npp = npp;
1360 newInstance->testObject = browser->createobject(npp, content::GetTestClass());
1361 newInstance->rememberedObject = 0;
1362 newInstance->eventLogging = false;
1363 newInstance->onStreamLoad = 0;
1364 newInstance->onStreamDestroy = 0;
1365 newInstance->onDestroy = 0;
1366 newInstance->onURLNotify = 0;
1367 newInstance->onSetWindow = 0;
1368 newInstance->onPaintEvent = 0;
1369 newInstance->logDestroy = false;
1370 newInstance->logSetWindow = false;
1371 newInstance->returnErrorFromNewStream = false;
1372 newInstance->returnNegativeOneFromWrite = false;
1373 newInstance->stream = 0;
1375 newInstance->firstUrl = 0;
1376 newInstance->firstHeaders = 0;
1377 newInstance->lastUrl = 0;
1378 newInstance->lastHeaders = 0;
1380 newInstance->testGetURLOnDestroy = false;
1381 newInstance->testWindowOpen = false;
1382 newInstance->testKeyboardFocusForPlugins = false;
1384 newInstance->mouseDownForEvaluateScript = false;
1385 newInstance->evaluateScriptOnMouseDownOrKeyDown = 0;
1387 return (NPObject*)newInstance;
1390 static void pluginDeallocate(NPObject* header) {
1391 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1392 delete plugin->pluginTest;
1393 if (plugin->testObject)
1394 browser->releaseobject(plugin->testObject);
1395 if (plugin->rememberedObject)
1396 browser->releaseobject(plugin->rememberedObject);
1398 free(plugin->firstUrl);
1399 free(plugin->firstHeaders);
1400 free(plugin->lastUrl);
1401 free(plugin->lastHeaders);
1402 free(plugin);
1405 void handleCallback(PluginObject* object,
1406 const char* url,
1407 NPReason reason,
1408 void* notifyData) {
1409 assert(object);
1411 NPVariant args[2];
1413 NPObject* windowScriptObject;
1414 browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
1416 NPIdentifier callbackIdentifier = notifyData;
1418 INT32_TO_NPVARIANT(reason, args[0]);
1420 char* strHdr = 0;
1421 if (object->firstUrl && object->firstHeaders && object->lastUrl &&
1422 object->lastHeaders) {
1423 // Format expected by JavaScript validator: four fields separated by \n\n:
1424 // First URL; first header block; last URL; last header block.
1425 // Note that header blocks already end with \n due to how NPStream::headers
1426 // works.
1427 int len = strlen(object->firstUrl) + 2 + strlen(object->firstHeaders) + 1 +
1428 strlen(object->lastUrl) + 2 + strlen(object->lastHeaders) + 1;
1429 strHdr = (char*)malloc(len + 1);
1430 snprintf(strHdr,
1431 len + 1,
1432 "%s\n\n%s\n%s\n\n%s\n",
1433 object->firstUrl,
1434 object->firstHeaders,
1435 object->lastUrl,
1436 object->lastHeaders);
1437 STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
1438 } else
1439 NULL_TO_NPVARIANT(args[1]);
1441 NPVariant browserResult;
1442 if (browser->invoke(object->npp,
1443 windowScriptObject,
1444 callbackIdentifier,
1445 args,
1447 &browserResult))
1448 browser->releasevariantvalue(&browserResult);
1450 free(strHdr);
1453 void notifyStream(PluginObject* object, const char* url, const char* headers) {
1454 if (!object->firstUrl) {
1455 if (url)
1456 object->firstUrl = base::strdup(url);
1457 if (headers)
1458 object->firstHeaders = base::strdup(headers);
1459 } else {
1460 free(object->lastUrl);
1461 free(object->lastHeaders);
1462 object->lastUrl = (url ? base::strdup(url) : 0);
1463 object->lastHeaders = (headers ? base::strdup(headers) : 0);
1467 void testNPRuntime(NPP npp) {
1468 NPObject* windowScriptObject;
1469 browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject);
1471 // Invoke
1472 NPIdentifier testNPInvoke = browser->getstringidentifier("testNPInvoke");
1473 NPVariant args[7];
1475 VOID_TO_NPVARIANT(args[0]);
1476 NULL_TO_NPVARIANT(args[1]);
1477 BOOLEAN_TO_NPVARIANT(true, args[2]);
1478 INT32_TO_NPVARIANT(242, args[3]);
1479 DOUBLE_TO_NPVARIANT(242.242, args[4]);
1480 STRINGZ_TO_NPVARIANT("Hello, World", args[5]);
1481 OBJECT_TO_NPVARIANT(windowScriptObject, args[6]);
1483 NPVariant result;
1484 if (browser->invoke(npp, windowScriptObject, testNPInvoke, args, 7, &result))
1485 browser->releasevariantvalue(&result);
1487 browser->releaseobject(windowScriptObject);