зеркало из https://github.com/mozilla/gecko-dev.git
Bug 518924. Add tests for NPAPI timers and async callbacks. r=bsmedberg
This commit is contained in:
Родитель
edf96c8bc4
Коммит
cf33b7cd2a
|
@ -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))
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<window title="NPAPI Timer Tests"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<title>NPAPI Timer Tests</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<body xmlns="http://www.w3.org/1999/xhtml" onload="runTests()">
|
||||
<embed id="plugin" type="application/x-test" width="50" height="50"></embed>
|
||||
</body>
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var uniqueIDTestFinished = false;
|
||||
var shortOneShotTimerFiredOnce = false;
|
||||
var shortOneShotTimerFiredTwice = false;
|
||||
var longRepeatingTimerFiredOnce = false;
|
||||
var longRepeatingTimerFiredTwice = false;
|
||||
|
||||
function uniqueID(success) {
|
||||
is(success, true, "Timers incorrectly given non-unique IDs.");
|
||||
uniqueIDTestFinished = true;
|
||||
}
|
||||
|
||||
function shortTimerFired() {
|
||||
is(uniqueIDTestFinished, true, "Unique ID test should have reported back before short timer fired.");
|
||||
if (shortOneShotTimerFiredOnce)
|
||||
shortOneShotTimerFiredTwice = true;
|
||||
else
|
||||
shortOneShotTimerFiredOnce = true;
|
||||
}
|
||||
|
||||
function longTimerFired() {
|
||||
is(shortOneShotTimerFiredOnce, true, "Short one-shot timer did not fire.");
|
||||
is(shortOneShotTimerFiredTwice, false, "Short one-shot timer fired multiple times.");
|
||||
|
||||
if (longRepeatingTimerFiredOnce) {
|
||||
var p = document.getElementById("plugin");
|
||||
p.unscheduleAllTimers();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
else {
|
||||
longRepeatingTimerFiredOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
var p = document.getElementById("plugin");
|
||||
p.timerTest();
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
|
@ -0,0 +1,33 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>NPN_AsyncCallback Tests</title>
|
||||
<script type="text/javascript"
|
||||
src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="runTests()">
|
||||
<p id="display"></p>
|
||||
|
||||
<embed id="plugin1" type="application/x-test" width="400" height="100">
|
||||
</embed>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function asyncTestsComplete(result) {
|
||||
ok(result, "asyncCallback tests completed");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
var plugin = document.getElementById("plugin1");
|
||||
plugin.asyncCallbackTest("asyncTestsComplete");
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>NPN_Timer Tests</title>
|
||||
<script type="text/javascript"
|
||||
src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="runTests()">
|
||||
<p id="display"></p>
|
||||
|
||||
<embed id="plugin1" type="application/x-test" width="400" height="100">
|
||||
</embed>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function pluginTimerTestFinish(result) {
|
||||
ok(result, "timer tests completed");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
var plugin = document.getElementById("plugin1");
|
||||
plugin.timerTest("pluginTimerTestFinish");
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -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:
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#define getpid _getpid
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#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<InstanceData*>(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<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(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<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(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<InstanceData*>(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<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(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<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(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<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(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<TestNPObject*>(npobj)->npp;
|
||||
InstanceData* id = static_cast<InstanceData*>(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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче