diff --git a/modules/plugin/test/mochitest/Makefile.in b/modules/plugin/test/mochitest/Makefile.in
index 344110652c9..838315de572 100644
--- a/modules/plugin/test/mochitest/Makefile.in
+++ b/modules/plugin/test/mochitest/Makefile.in
@@ -70,6 +70,8 @@ _MOCHITEST_FILES = \
test_streamNotify.html \
test_instantiation.html \
test_cookies.html \
+ test_npn_timers.html \
+ test_npn_asynccall.html \
$(NULL)
# test_npruntime_npnsetexception.html \ Disabled for e10s
@@ -93,7 +95,6 @@ _MOCHICHROME_FILES = \
test_npruntime.xul \
test_privatemode.xul \
test_wmode.xul \
- test_npapi_timers.xul \
$(NULL)
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
diff --git a/modules/plugin/test/mochitest/test_npapi_timers.xul b/modules/plugin/test/mochitest/test_npapi_timers.xul
deleted file mode 100644
index 38f2c3d1eb3..00000000000
--- a/modules/plugin/test/mochitest/test_npapi_timers.xul
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
- NPAPI Timer Tests
-
-
-
-
-
-
-
diff --git a/modules/plugin/test/mochitest/test_npn_asynccall.html b/modules/plugin/test/mochitest/test_npn_asynccall.html
new file mode 100644
index 00000000000..6a6a0a04e51
--- /dev/null
+++ b/modules/plugin/test/mochitest/test_npn_asynccall.html
@@ -0,0 +1,33 @@
+
+
+ NPN_AsyncCallback Tests
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/plugin/test/mochitest/test_npn_timers.html b/modules/plugin/test/mochitest/test_npn_timers.html
new file mode 100644
index 00000000000..da9f1897c72
--- /dev/null
+++ b/modules/plugin/test/mochitest/test_npn_timers.html
@@ -0,0 +1,33 @@
+
+
+ NPN_Timer Tests
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/plugin/test/testplugin/README b/modules/plugin/test/testplugin/README
index f679bcb8002..11a44e3e6a7 100644
--- a/modules/plugin/test/testplugin/README
+++ b/modules/plugin/test/testplugin/README
@@ -86,6 +86,14 @@ NPN_GetAuthenticationInfo(). Returns a string "username|password" for
the specified auth criteria, or throws an exception if no data is
available.
+* timerTest(callback) - initiates tests of NPN_ScheduleTimer &
+NPN_UnscheduleTimer. When finished, calls the script callback
+with a boolean value, indicating whether the tests were successful.
+
+* asyncCallbackTest(callback) - initiates tests of
+NPN_PluginThreadAsyncCall. When finished, calls the script callback
+with a boolean value, indicating whether the tests were successful.
+
== Private browsing ==
The test plugin object supports the following scriptable methods:
diff --git a/modules/plugin/test/testplugin/nptest.cpp b/modules/plugin/test/testplugin/nptest.cpp
index 10688ac07ca..e8973d5252f 100644
--- a/modules/plugin/test/testplugin/nptest.cpp
+++ b/modules/plugin/test/testplugin/nptest.cpp
@@ -49,6 +49,7 @@
#define getpid _getpid
#else
#include
+#include
#endif
using namespace std;
@@ -95,6 +96,8 @@ static NPClass sNPClass;
static void
testplugin_URLNotify(NPP instance, const char* url, NPReason reason,
void* notifyData);
+void
+asyncCallback(void* cookie);
//
// identifiers
@@ -118,7 +121,6 @@ static bool getClipRegionRectEdge(NPObject* npobj, const NPVariant* args, uint32
static bool startWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
-static bool unscheduleAllTimers(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getLastMouseY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getPaintCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
@@ -138,6 +140,7 @@ static bool enableFPExceptions(NPObject* npobj, const NPVariant* args, uint32_t
static bool setCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static bool getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
+static bool asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
static const NPUTF8* sPluginMethodIdentifierNames[] = {
"npnEvaluateTest",
@@ -155,7 +158,6 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
"startWatchingInstanceCount",
"getInstanceCount",
"stopWatchingInstanceCount",
- "unscheduleAllTimers",
"getLastMouseX",
"getLastMouseY",
"getPaintCount",
@@ -175,6 +177,7 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
"setCookie",
"getCookie",
"getAuthInfo",
+ "asyncCallbackTest",
};
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMethodIdentifierNames)] = {
@@ -193,7 +196,6 @@ static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMetho
startWatchingInstanceCount,
getInstanceCount,
stopWatchingInstanceCount,
- unscheduleAllTimers,
getLastMouseX,
getLastMouseY,
getPaintCount,
@@ -213,6 +215,7 @@ static const ScriptableFunction sPluginMethodFunctions[ARRAY_LENGTH(sPluginMetho
setCookie,
getCookie,
getAuthInfo,
+ asyncCallbackTest,
};
struct URLNotifyData
@@ -234,6 +237,30 @@ static const char* SUCCESS_STRING = "pass";
static bool sIdentifiersInitialized = false;
+static uint32_t timerEventCount = 0;
+
+struct timerEvent {
+ int32_t timerIdReceive;
+ int32_t timerIdSchedule;
+ uint32_t timerInterval;
+ bool timerRepeat;
+ int32_t timerIdUnschedule;
+};
+static timerEvent timerEvents[] = {
+ {-1, 0, 200, false, -1},
+ {0, 0, 400, false, -1},
+ {0, 0, 200, true, -1},
+ {0, 1, 100, true, -1},
+ {1, -1, 0, false, -1},
+ {0, -1, 0, false, -1},
+ {1, -1, 0, false, -1},
+ {1, -1, 0, false, -1},
+ {0, -1, 0, false, 0},
+ {1, 2, 600, false, 1},
+ {2, -1, 0, false, 2},
+};
+static uint32_t totalTimerEvents = sizeof(timerEvents) / sizeof(timerEvent);
+
/**
* Incremented for every startWatchingInstanceCount.
*/
@@ -1348,6 +1375,12 @@ NPN_GetAuthenticationInfo(NPP instance,
username, ulen, password, plen);
}
+void
+NPN_PluginThreadAsyncCall(NPP plugin, void (*func)(void*), void* userdata)
+{
+ return sBrowserFuncs->pluginthreadasynccall(plugin, func, userdata);
+}
+
//
// npruntime object functions
//
@@ -1726,49 +1759,6 @@ identifierToStringTest(NPObject* npobj, const NPVariant* args, uint32_t argCount
return true;
}
-static void timerCallback(NPP npp, uint32_t timerID)
-{
- InstanceData* id = static_cast(npp->pdata);
-
- NPObject* windowObject;
- NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
- if (!windowObject)
- return;
-
- NPVariant rval;
- if (timerID == id->timerID1)
- NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier("shortTimerFired"), NULL, 0, &rval);
- else if (timerID == id->timerID2)
- NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier("longTimerFired"), NULL, 0, &rval);
-
- NPN_ReleaseObject(windowObject);
-}
-
-static bool
-timerTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
-{
- NPP npp = static_cast(npobj)->npp;
- InstanceData* id = static_cast(npp->pdata);
-
- NPObject* windowObject;
- NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
- if (!windowObject)
- return false;
-
- id->timerID1 = NPN_ScheduleTimer(npp, 50, false, timerCallback);
- id->timerID2 = NPN_ScheduleTimer(npp, 150, true, timerCallback);
-
- NPVariant rval;
- NPVariant uniqueIDArgs[1];
- BOOLEAN_TO_NPVARIANT((id->timerID1 != id->timerID2), uniqueIDArgs[0]);
- NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier("uniqueID"), uniqueIDArgs, 1, &rval);
- NPN_ReleaseVariantValue(&uniqueIDArgs[0]);
-
- NPN_ReleaseObject(windowObject);
-
- return true;
-}
-
static bool
queryPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
@@ -1898,20 +1888,6 @@ stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCo
return true;
}
-static bool
-unscheduleAllTimers(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
-{
- NPP npp = static_cast(npobj)->npp;
- InstanceData* id = static_cast(npp->pdata);
-
- NPN_UnscheduleTimer(npp, id->timerID1);
- id->timerID1 = 0;
- NPN_UnscheduleTimer(npp, id->timerID2);
- id->timerID2 = 0;
-
- return true;
-}
-
static bool
getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
@@ -2348,3 +2324,125 @@ getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant
return true;
}
+
+static void timerCallback(NPP npp, uint32_t timerID)
+{
+ InstanceData* id = static_cast(npp->pdata);
+ timerEventCount++;
+ timerEvent event = timerEvents[timerEventCount];
+
+ NPObject* windowObject;
+ NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
+ if (!windowObject)
+ return;
+
+ NPVariant rval;
+ if (timerID != id->timerID[event.timerIdReceive])
+ id->timerTestResult = false;
+
+ if (timerEventCount == totalTimerEvents - 1) {
+ NPVariant arg;
+ BOOLEAN_TO_NPVARIANT(id->timerTestResult, arg);
+ NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier(id->timerTestScriptCallback.c_str()), &arg, 1, &rval);
+ NPN_ReleaseVariantValue(&arg);
+ }
+
+ NPN_ReleaseObject(windowObject);
+
+ if (event.timerIdSchedule > -1) {
+ id->timerID[event.timerIdSchedule] = NPN_ScheduleTimer(npp, event.timerInterval, event.timerRepeat, timerCallback);
+ }
+ if (event.timerIdUnschedule > -1) {
+ NPN_UnscheduleTimer(npp, id->timerID[event.timerIdUnschedule]);
+ }
+}
+
+static bool
+timerTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ NPP npp = static_cast(npobj)->npp;
+ InstanceData* id = static_cast(npp->pdata);
+ timerEventCount = 0;
+
+ if (argCount < 1 || !NPVARIANT_IS_STRING(args[0]))
+ return false;
+ const NPString* argstr = &NPVARIANT_TO_STRING(args[0]);
+ id->timerTestScriptCallback = argstr->UTF8Characters;
+
+ id->timerTestResult = true;
+ timerEvent event = timerEvents[timerEventCount];
+
+ id->timerID[event.timerIdSchedule] = NPN_ScheduleTimer(npp, event.timerInterval, event.timerRepeat, timerCallback);
+
+ return id->timerID[event.timerIdSchedule] != 0;
+}
+
+#ifdef XP_WIN
+void
+ThreadProc(void* cookie)
+#else
+void*
+ThreadProc(void* cookie)
+#endif
+{
+ NPObject* npobj = (NPObject*)cookie;
+ NPP npp = static_cast(npobj)->npp;
+ InstanceData* id = static_cast(npp->pdata);
+ id->asyncTestPhase = 1;
+ NPN_PluginThreadAsyncCall(npp, asyncCallback, (void*)npobj);
+#ifndef XP_WIN
+ return NULL;
+#endif
+}
+
+void
+asyncCallback(void* cookie)
+{
+ NPObject* npobj = (NPObject*)cookie;
+ NPP npp = static_cast(npobj)->npp;
+ InstanceData* id = static_cast(npp->pdata);
+
+ switch (id->asyncTestPhase) {
+ // async callback triggered from same thread
+ case 0:
+#ifdef XP_WIN
+ if (_beginthread(ThreadProc, 0, (void*)npobj) == -1)
+ id->asyncCallbackResult = false;
+#else
+ pthread_t tid;
+ if (pthread_create(&tid, 0, ThreadProc, (void*)npobj))
+ id->asyncCallbackResult = false;
+#endif
+ break;
+
+ // async callback triggered from different thread
+ default:
+ NPObject* windowObject;
+ NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
+ if (!windowObject)
+ return;
+ NPVariant arg, rval;
+ BOOLEAN_TO_NPVARIANT(id->asyncCallbackResult, arg);
+ NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier(id->asyncTestScriptCallback.c_str()), &arg, 1, &rval);
+ NPN_ReleaseVariantValue(&arg);
+ break;
+ }
+}
+
+static bool
+asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ NPP npp = static_cast(npobj)->npp;
+ InstanceData* id = static_cast(npp->pdata);
+
+ if (argCount < 1 || !NPVARIANT_IS_STRING(args[0]))
+ return false;
+ const NPString* argstr = &NPVARIANT_TO_STRING(args[0]);
+ id->asyncTestScriptCallback = argstr->UTF8Characters;
+
+ id->asyncTestPhase = 0;
+ id->asyncCallbackResult = true;
+ NPN_PluginThreadAsyncCall(npp, asyncCallback, (void*)npobj);
+
+ return true;
+}
diff --git a/modules/plugin/test/testplugin/nptest.h b/modules/plugin/test/testplugin/nptest.h
index e56ce11ec3e..1cbad234237 100644
--- a/modules/plugin/test/testplugin/nptest.h
+++ b/modules/plugin/test/testplugin/nptest.h
@@ -92,8 +92,9 @@ typedef struct InstanceData {
bool hasWidget;
bool npnNewStream;
bool throwOnNextInvoke;
- uint32_t timerID1;
- uint32_t timerID2;
+ uint32_t timerID[2];
+ bool timerTestResult;
+ bool asyncCallbackResult;
int32_t winX;
int32_t winY;
int32_t lastMouseX;
@@ -102,12 +103,15 @@ typedef struct InstanceData {
int32_t paintCount;
int32_t writeCount;
int32_t writeReadyCount;
+ int32_t asyncTestPhase;
TestFunction testFunction;
TestFunction functionToFail;
NPError failureCode;
PostMode postMode;
std::string testUrl;
std::string frame;
+ std::string timerTestScriptCallback;
+ std::string asyncTestScriptCallback;
std::ostringstream err;
uint16_t streamMode;
int32_t streamChunkSize;