Bug 1352572 - Add generic callback handling mechanism to testplugin; r?bsmedberg draft
authorLie Ryan <lie.1296@gmail.com>
Sat, 08 Apr 2017 15:23:13 +0000
changeset 569524 43248d7bc0c54f6c1edad1f5395dc3cfb92e2d28
parent 569523 f0dd230e85b6baa346c66679a071be8e6f1f75f5
child 569525 6a0c794aa4a80df7f7ceceee624932f5ef762c54
push id56209
push userbmo:lie.1296@gmail.com
push dateThu, 27 Apr 2017 16:02:13 +0000
reviewersbsmedberg
bugs1352572
milestone55.0a1
Bug 1352572 - Add generic callback handling mechanism to testplugin; r?bsmedberg MozReview-Commit-ID: 2aMLrtHPm05
dom/plugins/test/testplugin/README
dom/plugins/test/testplugin/nptest.cpp
dom/plugins/test/testplugin/nptest.h
--- a/dom/plugins/test/testplugin/README
+++ b/dom/plugins/test/testplugin/README
@@ -31,16 +31,21 @@ unsupported platforms this will fallback
 The plugin will use the NPAPI Async DXGI drawing model extension. Only
 supported on Windows Vista or higher. On unsupported platforms this will
 fallback to non-async rendering.
 
 * color
 This specifies the color to use for drawmode="solid". The value should be 8 hex
 digits, 2 per channel in AARRGGBB format.
 
+* on* 
+Any parameters starting with 'on' (e.g. onload, ondestroystream, onabluemoon)
+can contain javascript snippets that will be called by the test plugin at
+various times. Refer to nptest.cpp source for what events are implemented.
+
 == Generic API Tests ==
 
 * setUndefinedValueTest
 Attempts to set the value of an undefined variable (0x0) via NPN_SetValue,
 returns true if it succeeds and false if it doesn't. It should never succeed.
 
 * .getReflector()
 Hands back an object which reflects properties as values, e.g.
--- a/dom/plugins/test/testplugin/nptest.cpp
+++ b/dom/plugins/test/testplugin/nptest.cpp
@@ -646,16 +646,18 @@ drawAsyncBitmapColor(InstanceData* insta
   }
 
   NPN_SetCurrentAsyncSurface(npp, instanceData->backBuffer, NULL);
   NPAsyncSurface *oldFront = instanceData->frontBuffer;
   instanceData->frontBuffer = instanceData->backBuffer;
   instanceData->backBuffer = oldFront;
 }
 
+bool dispatchCallback(InstanceData* instanceData, const char* eventName);
+
 //
 // function signatures
 //
 
 NPObject* scriptableAllocate(NPP npp, NPClass* aClass);
 void scriptableDeallocate(NPObject* npobj);
 void scriptableInvalidate(NPObject* npobj);
 bool scriptableHasMethod(NPObject* npobj, NPIdentifier name);
@@ -1016,16 +1018,20 @@ NPP_New(NPMIMEType pluginType, NPP insta
     // We don't support NP_FULL any more, but name="plugin" is an indication
     // that we're a full-page plugin. We use default seek parameters for
     // test_fullpage.html
     if (strcmp(argn[i], "name") == 0 && strcmp(argv[i], "plugin") == 0) {
       instanceData->streamMode = NP_SEEK;
       instanceData->frame = "testframe";
       addRange(instanceData, "100,100");
     }
+
+    if (strncmp(argn[i], "on", strlen("on")) == 0) {
+      instanceData->callbacks[argn[i]] = argv[i];
+    }
   }
 
   if (!browserSupportsWindowless || !pluginSupportsWindowlessMode()) {
     requestWindow = true;
   } else if (!pluginSupportsWindowMode()) {
     requestWindow = false;
   }
   if (requestWindow) {
@@ -1347,16 +1353,18 @@ NPP_DestroyStream(NPP instance, NPStream
   }
   if (instanceData->testFunction == FUNCTION_NPP_POSTURL) {
     NPError err = NPN_PostURL(instance, instanceData->testUrl.c_str(),
       instanceData->postMode == POSTMODE_FRAME ? instanceData->frame.c_str() : nullptr,
       instanceData->streamBufSize,
       reinterpret_cast<char *>(instanceData->streamBuf), false);
     if (err != NPERR_NO_ERROR)
       instanceData->err << "Error: NPN_PostURL returned error value " << err;
+
+    dispatchCallback(instanceData, "onposturlcomplete");
   }
   return NPERR_NO_ERROR;
 }
 
 int32_t
 NPP_WriteReady(NPP instance, NPStream* stream)
 {
   InstanceData* instanceData = (InstanceData*)(instance->pdata);
@@ -4029,8 +4037,36 @@ getAudioMuted(NPObject* npobj, const NPV
     return false;
   }
 
   NPP npp = static_cast<TestNPObject*>(npobj)->npp;
   InstanceData* id = static_cast<InstanceData*>(npp->pdata);
   BOOLEAN_TO_NPVARIANT(id->audioMuted, *result);
   return true;
 }
+
+bool
+dispatchCallback(InstanceData* instanceData, const char* eventName)
+{
+  NPVariant npScript;
+  {
+    auto script = instanceData->callbacks.find(eventName);
+    if (script == instanceData->callbacks.end()) { return false; }
+    STRINGZ_TO_NPVARIANT(NPN_StrDup(script->second.c_str()), npScript);
+  }
+
+  NPObject* windowObject;
+  {
+    NPError err = NPN_GetValue(instanceData->npp, NPNVWindowNPObject, &windowObject);
+    if (err != NPERR_NO_ERROR) { return false; }
+  }
+
+  {
+    NPVariant evalResult;
+    bool ok = NPN_Evaluate(instanceData->npp, windowObject, &NPVARIANT_TO_STRING(npScript), &evalResult);
+    if (!ok) { return false; }
+    NPN_ReleaseVariantValue(&evalResult);
+  }
+
+  NPN_ReleaseObject(windowObject);
+  NPN_ReleaseVariantValue(&npScript);
+  return true;
+}
--- a/dom/plugins/test/testplugin/nptest.h
+++ b/dom/plugins/test/testplugin/nptest.h
@@ -34,16 +34,17 @@
 #ifndef nptest_h_
 #define nptest_h_
 
 #include "mozilla-config.h"
 
 #include "npapi.h"
 #include "npfunctions.h"
 #include "npruntime.h"
+#include <map>
 #include <stdint.h>
 #include <string>
 #include <sstream>
 
 typedef enum  {
   DM_DEFAULT,
   DM_SOLID_COLOR
 } DrawMode;
@@ -154,16 +155,17 @@ typedef struct InstanceData {
   int32_t bugMode;
   std::string javaCodebase;
   AsyncDrawing asyncDrawing;
   NPAsyncSurface *frontBuffer;
   NPAsyncSurface *backBuffer;
   std::string lastComposition;
   void* placeholderWnd;
   double cssZoomFactor;
+  std::map<std::string, std::string> callbacks;
 } InstanceData;
 
 void notifyDidPaint(InstanceData* instanceData);
 
 #if defined(XP_WIN)
 bool setupDxgiSurfaces(NPP npp, InstanceData* instanceData);
 void drawDxgiBitmapColor(InstanceData* instanceData);
 #endif