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;