Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / content / shell / tools / plugin / PluginObject.cpp
bloba28109bb69fcf196d44e653ef78d7e4db18fc3a3
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 plug-in'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 NPObject* script_object = object_result.value.objectValue;
974 // Arg2 is the name of the method to be called on the script object
975 NPUTF8* object_mehod_string = createCStringFromNPVariant(&args[1]);
976 NPIdentifier object_method =
977 browser->getstringidentifier(object_mehod_string);
978 free(object_mehod_string);
980 // Create a fresh NPObject to be passed as an argument
981 NPObject* object_arg = browser->createobject(obj->npp, obj->header._class);
983 NPVariant invoke_args[1];
984 OBJECT_TO_NPVARIANT(object_arg, invoke_args[0]);
986 // Invoke the script method
987 NPVariant object_method_result;
988 browser->invoke(obj->npp,
989 script_object,
990 object_method,
991 invoke_args,
993 &object_method_result);
995 browser->releasevariantvalue(&object_result);
996 VOID_TO_NPVARIANT(*result);
997 if (NPVARIANT_IS_OBJECT(object_method_result)) {
998 // Now return the callbacks return value back to our caller.
999 // BUG 897451: This should be the same as the
1000 // windowScriptObject, but its not (in Chrome) - or at least, it
1001 // has a different refcount. This means Chrome will delete the
1002 // object before returning it and the calling JS gets a garbage
1003 // value. Firefox handles it fine.
1004 OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(object_method_result), *result);
1005 } else {
1006 browser->releasevariantvalue(&object_method_result);
1007 VOID_TO_NPVARIANT(*result);
1010 browser->releaseobject(object_arg);
1012 return true;
1015 // Helper function to notify the layout test controller that the test completed.
1016 void notifyTestCompletion(NPP npp, NPObject* object) {
1017 NPVariant result;
1018 NPString script;
1019 script.UTF8Characters = "javascript:window.testRunner.notifyDone();";
1020 script.UTF8Length = strlen("javascript:window.testRunner.notifyDone();");
1021 browser->evaluate(npp, object, &script, &result);
1022 browser->releasevariantvalue(&result);
1025 bool testDocumentOpen(NPP npp) {
1026 NPIdentifier documentId = browser->getstringidentifier("document");
1027 NPIdentifier openId = browser->getstringidentifier("open");
1029 NPObject* windowObject = 0;
1030 browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
1031 if (!windowObject)
1032 return false;
1034 NPVariant docVariant;
1035 browser->getproperty(npp, windowObject, documentId, &docVariant);
1036 if (docVariant.type != NPVariantType_Object) {
1037 browser->releaseobject(windowObject);
1038 return false;
1041 NPObject* documentObject = NPVARIANT_TO_OBJECT(docVariant);
1043 NPVariant openArgs[2];
1044 STRINGZ_TO_NPVARIANT("text/html", openArgs[0]);
1045 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);
1047 NPVariant result;
1048 if (!browser->invoke(npp, documentObject, openId, openArgs, 2, &result)) {
1049 browser->releaseobject(windowObject);
1050 browser->releaseobject(documentObject);
1051 return false;
1054 browser->releaseobject(documentObject);
1056 if (result.type != NPVariantType_Object) {
1057 browser->releaseobject(windowObject);
1058 browser->releasevariantvalue(&result);
1059 return false;
1062 pluginLogWithWindowObject(windowObject, npp, "PLUGIN: DOCUMENT OPEN SUCCESS");
1063 notifyTestCompletion(npp, result.value.objectValue);
1064 browser->releaseobject(result.value.objectValue);
1065 browser->releaseobject(windowObject);
1066 return true;
1069 bool testWindowOpen(NPP npp) {
1070 NPIdentifier openId = browser->getstringidentifier("open");
1072 NPObject* windowObject = 0;
1073 browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
1074 if (!windowObject)
1075 return false;
1077 NPVariant openArgs[2];
1078 STRINGZ_TO_NPVARIANT("about:blank", openArgs[0]);
1079 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);
1081 NPVariant result;
1082 if (!browser->invoke(npp, windowObject, openId, openArgs, 2, &result)) {
1083 browser->releaseobject(windowObject);
1084 return false;
1087 if (result.type != NPVariantType_Object) {
1088 browser->releaseobject(windowObject);
1089 browser->releasevariantvalue(&result);
1090 return false;
1093 pluginLogWithWindowObject(windowObject, npp, "PLUGIN: WINDOW OPEN SUCCESS");
1094 notifyTestCompletion(npp, result.value.objectValue);
1095 browser->releaseobject(result.value.objectValue);
1096 browser->releaseobject(windowObject);
1097 return true;
1100 static bool testSetStatus(PluginObject* obj,
1101 const NPVariant* args,
1102 uint32_t argCount,
1103 NPVariant* result) {
1104 char* message = 0;
1105 if (argCount && NPVARIANT_IS_STRING(args[0])) {
1106 NPString statusString = NPVARIANT_TO_STRING(args[0]);
1107 message = toCString(statusString);
1110 browser->status(obj->npp, message);
1112 free(message);
1113 return true;
1116 static bool testResizeTo(PluginObject* obj,
1117 const NPVariant* args,
1118 uint32_t argCount,
1119 NPVariant* result) {
1120 VOID_TO_NPVARIANT(*result);
1122 NPObject* windowObject;
1123 if (NPERR_NO_ERROR !=
1124 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
1125 return false;
1127 NPVariant callResult;
1128 if (browser->invoke(obj->npp,
1129 windowObject,
1130 browser->getstringidentifier("resizePlugin"),
1131 args,
1132 argCount,
1133 &callResult))
1134 browser->releasevariantvalue(&callResult);
1136 // Force layout.
1137 if (browser->getproperty(obj->npp,
1138 windowObject,
1139 browser->getstringidentifier("pageYOffset"),
1140 &callResult))
1141 browser->releasevariantvalue(&callResult);
1143 return true;
1146 static bool normalizeOverride(PluginObject* obj,
1147 const NPVariant* args,
1148 uint32_t argCount,
1149 NPVariant* result) {
1150 VOID_TO_NPVARIANT(*result);
1152 NPObject* windowObject;
1153 if (NPERR_NO_ERROR !=
1154 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
1155 return false;
1157 NPVariant callResult;
1158 if (browser->invoke(obj->npp,
1159 windowObject,
1160 browser->getstringidentifier("pluginCallback"),
1161 args,
1162 argCount,
1163 &callResult))
1164 browser->releasevariantvalue(&callResult);
1166 return true;
1169 static bool invalidateRect(PluginObject* obj,
1170 const NPVariant* args,
1171 uint32_t argCount,
1172 NPVariant* result) {
1173 if (argCount != 4)
1174 return false;
1176 NPRect rect;
1177 rect.left = static_cast<int>(NPVARIANT_TO_DOUBLE(args[0]));
1178 rect.top = static_cast<int>(NPVARIANT_TO_DOUBLE(args[1]));
1179 rect.right = static_cast<int>(NPVARIANT_TO_DOUBLE(args[2]));
1180 rect.bottom = static_cast<int>(NPVARIANT_TO_DOUBLE(args[3]));
1182 browser->invalidaterect(obj->npp, &rect);
1183 return true;
1186 static bool objectsAreSame(PluginObject* obj,
1187 const NPVariant* args,
1188 uint32_t argCount,
1189 NPVariant* result) {
1190 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
1191 !NPVARIANT_IS_OBJECT(args[1]))
1192 return false;
1194 BOOLEAN_TO_NPVARIANT(
1195 NPVARIANT_TO_OBJECT(args[0]) == NPVARIANT_TO_OBJECT(args[1]), *result);
1196 return true;
1199 static bool pluginInvoke(NPObject* header,
1200 NPIdentifier name,
1201 const NPVariant* args,
1202 uint32_t argCount,
1203 NPVariant* result) {
1204 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1205 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD])
1206 return testCallback(plugin, args, argCount, result);
1207 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD_RETURN])
1208 return testCallbackReturn(plugin, args, argCount, result);
1209 if (name == pluginMethodIdentifiers[ID_TEST_GETURL])
1210 return getURL(plugin, args, argCount, result);
1211 if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS])
1212 return testDOMAccess(plugin, args, argCount, result);
1213 if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY])
1214 return getURLNotify(plugin, args, argCount, result);
1215 if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT])
1216 return testInvokeDefault(plugin, args, argCount, result);
1217 if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE])
1218 return testEnumerate(plugin, args, argCount, result);
1219 if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM])
1220 return destroyStream(plugin, args, argCount, result);
1221 if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER])
1222 return testGetIntIdentifier(plugin, args, argCount, result);
1223 if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE])
1224 return testEvaluate(plugin, args, argCount, result);
1225 if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY])
1226 return testGetProperty(plugin, args, argCount, result);
1227 if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE])
1228 return testGetPropertyReturnValue(plugin, args, argCount, result);
1229 if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY])
1230 return testHasProperty(plugin, args, argCount, result);
1231 if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD])
1232 return testHasMethod(plugin, args, argCount, result);
1233 if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING])
1234 return testIdentifierToString(plugin, args, argCount, result);
1235 if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT])
1236 return testIdentifierToInt(plugin, args, argCount, result);
1237 if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT])
1238 return testPassTestObject(plugin, args, argCount, result);
1239 if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE])
1240 return testPostURLFile(plugin, args, argCount, result);
1241 if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT])
1242 return testConstruct(plugin, args, argCount, result);
1243 if (name == pluginMethodIdentifiers[ID_TEST_SCRIPT_OBJECT_INVOKE])
1244 return testScriptObjectInvoke(plugin, args, argCount, result);
1245 if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) {
1246 browser->setexception(header, "plugin object testThrowException SUCCESS");
1247 return true;
1249 if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) {
1250 NPObject* windowScriptObject;
1251 browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);
1252 browser->invoke(
1253 plugin->npp, windowScriptObject, name, args, argCount, result);
1254 return false;
1256 if (name == pluginMethodIdentifiers[ID_TEST_CLONE_OBJECT]) {
1257 NPObject* new_object =
1258 browser->createobject(plugin->npp, plugin->header._class);
1259 assert(new_object->referenceCount == 1);
1260 OBJECT_TO_NPVARIANT(new_object, *result);
1261 return true;
1263 if (name == pluginMethodIdentifiers[ID_TEST_CREATE_TEST_OBJECT]) {
1264 NPObject* testObject =
1265 browser->createobject(plugin->npp, content::GetTestClass());
1266 assert(testObject->referenceCount == 1);
1267 OBJECT_TO_NPVARIANT(testObject, *result);
1268 return true;
1270 if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM])
1271 return destroyNullStream(plugin, args, argCount, result);
1272 if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) {
1273 browser->reloadplugins(false);
1274 return true;
1276 if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) {
1277 browser->reloadplugins(true);
1278 return true;
1280 if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) {
1281 browser->getproperty(plugin->npp,
1282 NPVARIANT_TO_OBJECT(args[0]),
1283 stringVariantToIdentifier(args[1]),
1284 result);
1285 return true;
1287 if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) {
1288 browser->setproperty(plugin->npp,
1289 NPVARIANT_TO_OBJECT(args[0]),
1290 stringVariantToIdentifier(args[1]),
1291 &args[2]);
1292 return true;
1294 if (name == pluginMethodIdentifiers[ID_REMEMBER]) {
1295 if (plugin->rememberedObject)
1296 browser->releaseobject(plugin->rememberedObject);
1297 plugin->rememberedObject = NPVARIANT_TO_OBJECT(args[0]);
1298 browser->retainobject(plugin->rememberedObject);
1299 VOID_TO_NPVARIANT(*result);
1300 return true;
1302 if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) {
1303 assert(plugin->rememberedObject);
1304 browser->retainobject(plugin->rememberedObject);
1305 OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
1306 return true;
1308 if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) {
1309 assert(plugin->rememberedObject);
1310 OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
1311 plugin->rememberedObject = 0;
1312 return true;
1314 if (name == pluginMethodIdentifiers[ID_REF_COUNT]) {
1315 uint32_t refCount = NPVARIANT_TO_OBJECT(args[0])->referenceCount;
1316 INT32_TO_NPVARIANT(refCount, *result);
1317 return true;
1319 if (name == pluginMethodIdentifiers[ID_SET_STATUS])
1320 return testSetStatus(plugin, args, argCount, result);
1321 if (name == pluginMethodIdentifiers[ID_RESIZE_TO])
1322 return testResizeTo(plugin, args, argCount, result);
1323 if (name == pluginMethodIdentifiers[ID_NORMALIZE])
1324 return normalizeOverride(plugin, args, argCount, result);
1325 if (name == pluginMethodIdentifiers[ID_INVALIDATE_RECT])
1326 return invalidateRect(plugin, args, argCount, result);
1327 if (name == pluginMethodIdentifiers[ID_OBJECTS_ARE_SAME])
1328 return objectsAreSame(plugin, args, argCount, result);
1329 if (name == pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]) {
1330 NPObject* newObject =
1331 browser->createobject(plugin->npp, plugin->header._class);
1332 OBJECT_TO_NPVARIANT(newObject, *result);
1333 callDeletePlugin(
1334 header, name, pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]);
1335 return true;
1337 return false;
1340 static void pluginInvalidate(NPObject* header) {
1341 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1342 plugin->testObject = 0;
1343 plugin->rememberedObject = 0;
1346 static NPObject* pluginAllocate(NPP npp, NPClass* theClass) {
1347 PluginObject* newInstance = (PluginObject*)malloc(sizeof(PluginObject));
1349 if (!identifiersInitialized) {
1350 identifiersInitialized = true;
1351 initializeIdentifiers();
1354 newInstance->pluginTest = 0;
1355 newInstance->npp = npp;
1356 newInstance->testObject = browser->createobject(npp, content::GetTestClass());
1357 newInstance->rememberedObject = 0;
1358 newInstance->eventLogging = false;
1359 newInstance->onStreamLoad = 0;
1360 newInstance->onStreamDestroy = 0;
1361 newInstance->onDestroy = 0;
1362 newInstance->onURLNotify = 0;
1363 newInstance->onSetWindow = 0;
1364 newInstance->onPaintEvent = 0;
1365 newInstance->logDestroy = false;
1366 newInstance->logSetWindow = false;
1367 newInstance->returnErrorFromNewStream = false;
1368 newInstance->returnNegativeOneFromWrite = false;
1369 newInstance->stream = 0;
1371 newInstance->firstUrl = 0;
1372 newInstance->firstHeaders = 0;
1373 newInstance->lastUrl = 0;
1374 newInstance->lastHeaders = 0;
1376 newInstance->testGetURLOnDestroy = false;
1377 newInstance->testWindowOpen = false;
1378 newInstance->testKeyboardFocusForPlugins = false;
1380 newInstance->mouseDownForEvaluateScript = false;
1381 newInstance->evaluateScriptOnMouseDownOrKeyDown = 0;
1383 return (NPObject*)newInstance;
1386 static void pluginDeallocate(NPObject* header) {
1387 PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
1388 delete plugin->pluginTest;
1389 if (plugin->testObject)
1390 browser->releaseobject(plugin->testObject);
1391 if (plugin->rememberedObject)
1392 browser->releaseobject(plugin->rememberedObject);
1394 free(plugin->firstUrl);
1395 free(plugin->firstHeaders);
1396 free(plugin->lastUrl);
1397 free(plugin->lastHeaders);
1398 free(plugin);
1401 void handleCallback(PluginObject* object,
1402 const char* url,
1403 NPReason reason,
1404 void* notifyData) {
1405 assert(object);
1407 NPVariant args[2];
1409 NPObject* windowScriptObject;
1410 browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
1412 NPIdentifier callbackIdentifier = notifyData;
1414 INT32_TO_NPVARIANT(reason, args[0]);
1416 char* strHdr = 0;
1417 if (object->firstUrl && object->firstHeaders && object->lastUrl &&
1418 object->lastHeaders) {
1419 // Format expected by JavaScript validator: four fields separated by \n\n:
1420 // First URL; first header block; last URL; last header block.
1421 // Note that header blocks already end with \n due to how NPStream::headers
1422 // works.
1423 int len = strlen(object->firstUrl) + 2 + strlen(object->firstHeaders) + 1 +
1424 strlen(object->lastUrl) + 2 + strlen(object->lastHeaders) + 1;
1425 strHdr = (char*)malloc(len + 1);
1426 snprintf(strHdr,
1427 len + 1,
1428 "%s\n\n%s\n%s\n\n%s\n",
1429 object->firstUrl,
1430 object->firstHeaders,
1431 object->lastUrl,
1432 object->lastHeaders);
1433 STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
1434 } else
1435 NULL_TO_NPVARIANT(args[1]);
1437 NPVariant browserResult;
1438 if (browser->invoke(object->npp,
1439 windowScriptObject,
1440 callbackIdentifier,
1441 args,
1443 &browserResult))
1444 browser->releasevariantvalue(&browserResult);
1446 free(strHdr);
1449 void notifyStream(PluginObject* object, const char* url, const char* headers) {
1450 if (!object->firstUrl) {
1451 if (url)
1452 object->firstUrl = base::strdup(url);
1453 if (headers)
1454 object->firstHeaders = base::strdup(headers);
1455 } else {
1456 free(object->lastUrl);
1457 free(object->lastHeaders);
1458 object->lastUrl = (url ? base::strdup(url) : 0);
1459 object->lastHeaders = (headers ? base::strdup(headers) : 0);
1463 void testNPRuntime(NPP npp) {
1464 NPObject* windowScriptObject;
1465 browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject);
1467 // Invoke
1468 NPIdentifier testNPInvoke = browser->getstringidentifier("testNPInvoke");
1469 NPVariant args[7];
1471 VOID_TO_NPVARIANT(args[0]);
1472 NULL_TO_NPVARIANT(args[1]);
1473 BOOLEAN_TO_NPVARIANT(true, args[2]);
1474 INT32_TO_NPVARIANT(242, args[3]);
1475 DOUBLE_TO_NPVARIANT(242.242, args[4]);
1476 STRINGZ_TO_NPVARIANT("Hello, World", args[5]);
1477 OBJECT_TO_NPVARIANT(windowScriptObject, args[6]);
1479 NPVariant result;
1480 if (browser->invoke(npp, windowScriptObject, testNPInvoke, args, 7, &result))
1481 browser->releasevariantvalue(&result);
1483 browser->releaseobject(windowScriptObject);