зеркало из https://github.com/mozilla/gecko-dev.git
Bug 826851: Unit tests for Plugin Hang UI. r=bsmedberg
This commit is contained in:
Родитель
263241169f
Коммит
b892ddd6ba
|
@ -308,6 +308,7 @@ PluginHangUIChild::HangUIDlgProc(HWND aDlgHandle, UINT aMsgCode, WPARAM aWParam,
|
||||||
}
|
}
|
||||||
case WM_DESTROY: {
|
case WM_DESTROY: {
|
||||||
EnableWindow(mParentWindow, TRUE);
|
EnableWindow(mParentWindow, TRUE);
|
||||||
|
SetForegroundWindow(mParentWindow);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -141,6 +141,11 @@ MOCHITEST_CHROME_FILES += \
|
||||||
test_idle_hang.xul \
|
test_idle_hang.xul \
|
||||||
test_busy_hang.xul \
|
test_busy_hang.xul \
|
||||||
hang_test.js \
|
hang_test.js \
|
||||||
|
test_hangui.xul \
|
||||||
|
hangui_subpage.html \
|
||||||
|
hangui_common.js \
|
||||||
|
hangui_iface.js \
|
||||||
|
dialog_watcher.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
const EVENT_OBJECT_SHOW = 0x8002;
|
||||||
|
const EVENT_OBJECT_HIDE = 0x8003;
|
||||||
|
const WINEVENT_OUTOFCONTEXT = 0;
|
||||||
|
const WINEVENT_SKIPOWNPROCESS = 2;
|
||||||
|
const QS_ALLINPUT = 0x04FF;
|
||||||
|
const INFINITE = 0xFFFFFFFF;
|
||||||
|
const WAIT_OBJECT_0 = 0;
|
||||||
|
const WAIT_TIMEOUT = 258;
|
||||||
|
const PM_NOREMOVE = 0;
|
||||||
|
|
||||||
|
function DialogWatcher(titleText, onDialogStart, onDialogEnd) {
|
||||||
|
this.titleText = titleText;
|
||||||
|
this.onDialogStart = onDialogStart;
|
||||||
|
this.onDialogEnd = onDialogEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogWatcher.prototype.init = function() {
|
||||||
|
this.hwnd = undefined;
|
||||||
|
if (!this.user32) {
|
||||||
|
this.user32 = ctypes.open("user32.dll");
|
||||||
|
}
|
||||||
|
if (!this.findWindow) {
|
||||||
|
this.findWindow = user32.declare("FindWindowW",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.jschar.ptr,
|
||||||
|
ctypes.jschar.ptr);
|
||||||
|
}
|
||||||
|
if (!this.winEventProcType) {
|
||||||
|
this.winEventProcType = ctypes.FunctionType(ctypes.stdcall_abi,
|
||||||
|
ctypes.void_t,
|
||||||
|
[ctypes.uintptr_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.long,
|
||||||
|
ctypes.long,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t]).ptr;
|
||||||
|
}
|
||||||
|
if (!this.setWinEventHook) {
|
||||||
|
this.setWinEventHook = user32.declare("SetWinEventHook",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
this.winEventProcType,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t);
|
||||||
|
}
|
||||||
|
if (!this.unhookWinEvent) {
|
||||||
|
this.unhookWinEvent = user32.declare("UnhookWinEvent",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.int,
|
||||||
|
ctypes.uintptr_t);
|
||||||
|
}
|
||||||
|
if (!this.pointType) {
|
||||||
|
this.pointType = ctypes.StructType("tagPOINT",
|
||||||
|
[ { "x": ctypes.long },
|
||||||
|
{ "y": ctypes.long } ] );
|
||||||
|
}
|
||||||
|
if (!this.msgType) {
|
||||||
|
this.msgType = ctypes.StructType("tagMSG",
|
||||||
|
[ { "hwnd": ctypes.uintptr_t },
|
||||||
|
{ "message": ctypes.uint32_t },
|
||||||
|
{ "wParam": ctypes.uintptr_t },
|
||||||
|
{ "lParam": ctypes.intptr_t },
|
||||||
|
{ "time": ctypes.uint32_t },
|
||||||
|
{ "pt": this.pointType } ] );
|
||||||
|
}
|
||||||
|
if (!this.peekMessage) {
|
||||||
|
this.peekMessage = user32.declare("PeekMessageW",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.int,
|
||||||
|
this.msgType.ptr,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t);
|
||||||
|
}
|
||||||
|
if (!this.msgWaitForMultipleObjects) {
|
||||||
|
this.msgWaitForMultipleObjects = user32.declare("MsgWaitForMultipleObjects",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uintptr_t.ptr,
|
||||||
|
ctypes.int,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uint32_t);
|
||||||
|
}
|
||||||
|
if (!this.getWindowTextW) {
|
||||||
|
this.getWindowTextW = user32.declare("GetWindowTextW",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.int,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.jschar.ptr,
|
||||||
|
ctypes.int);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DialogWatcher.prototype.getWindowText = function(hwnd) {
|
||||||
|
var bufType = ctypes.ArrayType(ctypes.jschar);
|
||||||
|
var buffer = new bufType(256);
|
||||||
|
|
||||||
|
if (this.getWindowTextW(hwnd, buffer, buffer.length)) {
|
||||||
|
return buffer.readString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DialogWatcher.prototype.processWindowEvents = function(timeout) {
|
||||||
|
var onWinEvent = function(self, hook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
|
||||||
|
var nhwnd = Number(hwnd)
|
||||||
|
if (event == EVENT_OBJECT_SHOW) {
|
||||||
|
if (nhwnd == self.hwnd) {
|
||||||
|
// We've already picked up this event via FindWindow
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var windowText = self.getWindowText(hwnd);
|
||||||
|
if (windowText == self.titleText && self.onDialogStart) {
|
||||||
|
self.hwnd = nhwnd;
|
||||||
|
self.onDialogStart(nhwnd);
|
||||||
|
}
|
||||||
|
} else if (event == EVENT_OBJECT_HIDE && nhwnd == self.hwnd && self.onDialogEnd) {
|
||||||
|
self.onDialogEnd();
|
||||||
|
self.hwnd = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var self = this;
|
||||||
|
var callback = this.winEventProcType(function(hook, event, hwnd, idObject,
|
||||||
|
idChild, dwEventThread,
|
||||||
|
dwmsEventTime) {
|
||||||
|
onWinEvent(self, hook, event, hwnd, idObject, idChild, dwEventThread,
|
||||||
|
dwmsEventTime);
|
||||||
|
} );
|
||||||
|
var hook = this.setWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_HIDE,
|
||||||
|
0, callback, 0, 0,
|
||||||
|
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
|
||||||
|
if (!hook) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check if the window is already showing
|
||||||
|
var hwnd = this.findWindow(null, this.titleText);
|
||||||
|
if (hwnd && hwnd > 0) {
|
||||||
|
this.hwnd = Number(hwnd);
|
||||||
|
if (this.onDialogStart) {
|
||||||
|
this.onDialogStart(this.hwnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!timeout) {
|
||||||
|
timeout = INFINITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var waitStatus = WAIT_OBJECT_0;
|
||||||
|
var expectingStart = this.onDialogStart && this.hwnd === undefined;
|
||||||
|
while (this.hwnd === undefined || this.onDialogEnd && this.hwnd) {
|
||||||
|
waitStatus = this.msgWaitForMultipleObjects(0, null, 0, expectingStart ?
|
||||||
|
INFINITE : timeout, 0);
|
||||||
|
if (waitStatus == WAIT_OBJECT_0) {
|
||||||
|
var msg = new this.msgType;
|
||||||
|
this.peekMessage(msg.address(), 0, 0, 0, PM_NOREMOVE);
|
||||||
|
} else if (waitStatus == WAIT_TIMEOUT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.unhookWinEvent(hook);
|
||||||
|
// Returns true if the hook was successful, something was found, and we never timed out
|
||||||
|
return this.hwnd !== undefined && waitStatus == WAIT_OBJECT_0;
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Plugin Hang UI constants
|
||||||
|
const HANGUIOP_NOTHING = 0;
|
||||||
|
const HANGUIOP_CANCEL = 1;
|
||||||
|
const HANGUIOP_COMMAND = 2;
|
||||||
|
const IDC_CONTINUE = 1001;
|
||||||
|
const IDC_STOP = 1002;
|
||||||
|
const IDC_NOFUTURE = 1003;
|
||||||
|
|
||||||
|
// Windows constants
|
||||||
|
const WM_CLOSE = 0x0010;
|
||||||
|
const WM_COMMAND = 0x0111;
|
||||||
|
const BM_GETCHECK = 0x00F0;
|
||||||
|
const BM_SETCHECK = 0x00F1;
|
||||||
|
const BN_CLICKED = 0;
|
||||||
|
const BST_CHECKED = 1;
|
||||||
|
|
||||||
|
// Test-specific constants
|
||||||
|
const EPSILON_MS = 1000;
|
||||||
|
const STALL_DURATION = 5;
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
var user32;
|
||||||
|
var sendMessage;
|
||||||
|
var getDlgItem;
|
||||||
|
var messageBox;
|
||||||
|
var watcher;
|
||||||
|
|
||||||
|
importScripts("hangui_common.js");
|
||||||
|
importScripts("dialog_watcher.js");
|
||||||
|
|
||||||
|
function initCTypes() {
|
||||||
|
if (!user32) {
|
||||||
|
user32 = ctypes.open("user32.dll");
|
||||||
|
}
|
||||||
|
if (!getDlgItem) {
|
||||||
|
getDlgItem = user32.declare("GetDlgItem",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.int);
|
||||||
|
}
|
||||||
|
if (!sendMessage) {
|
||||||
|
sendMessage = user32.declare("SendMessageW",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.intptr_t,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.uint32_t,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.intptr_t);
|
||||||
|
}
|
||||||
|
if (!messageBox) {
|
||||||
|
// Handy for debugging the test itself
|
||||||
|
messageBox = user32.declare("MessageBoxW",
|
||||||
|
ctypes.winapi_abi,
|
||||||
|
ctypes.int,
|
||||||
|
ctypes.uintptr_t,
|
||||||
|
ctypes.jschar.ptr,
|
||||||
|
ctypes.jschar.ptr,
|
||||||
|
ctypes.uint32_t);
|
||||||
|
}
|
||||||
|
if (!watcher) {
|
||||||
|
watcher = new DialogWatcher("Warning: Unresponsive plugin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function postSuccess(params) {
|
||||||
|
self.postMessage({"status": true, "params": params});
|
||||||
|
}
|
||||||
|
|
||||||
|
function postFail(params, msg) {
|
||||||
|
self.postMessage({"status": false, "params": params, "msg": msg});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDialogStart(inparams, hwnd) {
|
||||||
|
var params = Object.create(inparams);
|
||||||
|
params.testName += " (Start)";
|
||||||
|
params.callback = null;
|
||||||
|
if (!params.expectToFind) {
|
||||||
|
postFail(params, "Dialog showed when we weren't expecting it to!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (params.opCode == HANGUIOP_CANCEL) {
|
||||||
|
sendMessage(hwnd, WM_CLOSE, 0, 0);
|
||||||
|
} else if (params.opCode == HANGUIOP_COMMAND) {
|
||||||
|
if (params.check) {
|
||||||
|
var checkbox = getDlgItem(hwnd, IDC_NOFUTURE);
|
||||||
|
if (!checkbox) {
|
||||||
|
postFail(params, "Couldn't find checkbox");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendMessage(checkbox, BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
sendMessage(hwnd, WM_COMMAND, (BN_CLICKED << 16) | IDC_NOFUTURE, checkbox);
|
||||||
|
}
|
||||||
|
var button = getDlgItem(hwnd, params.commandId);
|
||||||
|
if (!button) {
|
||||||
|
postFail(params,
|
||||||
|
"GetDlgItem failed to find button with ID " + params.commandId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendMessage(hwnd, WM_COMMAND, (BN_CLICKED << 16) | params.commandId, button);
|
||||||
|
}
|
||||||
|
postSuccess(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDialogEnd(inparams) {
|
||||||
|
var params = Object.create(inparams);
|
||||||
|
params.testName += " (End)";
|
||||||
|
params.callback = inparams.callback;
|
||||||
|
postSuccess(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onmessage = function(event) {
|
||||||
|
initCTypes();
|
||||||
|
watcher.init();
|
||||||
|
var params = event.data;
|
||||||
|
var timeout = params.timeoutMs;
|
||||||
|
if (params.expectToFind) {
|
||||||
|
watcher.onDialogStart = function(hwnd) { onDialogStart(params, hwnd); };
|
||||||
|
if (params.expectToClose) {
|
||||||
|
watcher.onDialogEnd = function() { onDialogEnd(params); };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
watcher.onDialogStart = null;
|
||||||
|
watcher.onDialogEnd = null;
|
||||||
|
}
|
||||||
|
var result = watcher.processWindowEvents(timeout);
|
||||||
|
if (result === null) {
|
||||||
|
postFail(params, "Hook failed");
|
||||||
|
} else if (!result) {
|
||||||
|
if (params.expectToFind) {
|
||||||
|
postFail(params, "The dialog didn't show but we were expecting it to");
|
||||||
|
} else {
|
||||||
|
postSuccess(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onerror = function(event) {
|
||||||
|
var msg = "Error: " + event.message + " at " + event.filename + ":" + event.lineno;
|
||||||
|
postFail(null, msg);
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<html>
|
||||||
|
<body onload="window.parent.frameLoaded()">
|
||||||
|
<embed id="plugin1" type="application/x-test" width="400" height="400"></embed>
|
||||||
|
|
|
@ -0,0 +1,263 @@
|
||||||
|
<?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="Basic Plugin Tests"
|
||||||
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<title>Plugin Hang UI Test</title>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="http://mochi.test:8888/chrome/dom/plugins/test/hang_test.js" />
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="http://mochi.test:8888/chrome/dom/plugins/test/hangui_common.js" />
|
||||||
|
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<iframe id="iframe1" src="hangui_subpage.html" width="400" height="400"></iframe>
|
||||||
|
</body>
|
||||||
|
<script class="testbody" type="application/javascript">
|
||||||
|
<![CDATA[
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
const hangUITimeoutPref = "dom.ipc.plugins.hangUITimeoutSecs";
|
||||||
|
const hangUIMinDisplayPref = "dom.ipc.plugins.hangUIMinDisplaySecs";
|
||||||
|
const timeoutPref = "dom.ipc.plugins.timeoutSecs";
|
||||||
|
|
||||||
|
var worker = new ChromeWorker("hangui_iface.js");
|
||||||
|
worker.onmessage = function(event) {
|
||||||
|
var result = event.data;
|
||||||
|
var params = result.params;
|
||||||
|
var output = params.testName;
|
||||||
|
if (result.msg) {
|
||||||
|
output += ": " + result.msg;
|
||||||
|
}
|
||||||
|
ok(result.status, output);
|
||||||
|
if (params.callback) {
|
||||||
|
var cb = eval(params.callback);
|
||||||
|
var timeout = setTimeout(function() { clearTimeout(timeout); cb(); }, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
worker.onerror = function(event) {
|
||||||
|
var output = "Error: " + event.message + " at " + event.filename + ":" + event.lineno;
|
||||||
|
ok(false, output);
|
||||||
|
};
|
||||||
|
|
||||||
|
var iframe;
|
||||||
|
var p;
|
||||||
|
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||||
|
|
||||||
|
function hanguiOperation(testName, timeoutSec, expectFind, expectClose, opCode,
|
||||||
|
commandId, check, cb) {
|
||||||
|
var timeoutMs = timeoutSec * 1000 + EPSILON_MS;
|
||||||
|
worker.postMessage({ "timeoutMs": timeoutMs, "expectToFind": expectFind,
|
||||||
|
"expectToClose": expectClose, "opCode": opCode,
|
||||||
|
"commandId": commandId, "check": check,
|
||||||
|
"testName": testName, "callback": cb });
|
||||||
|
}
|
||||||
|
|
||||||
|
function hanguiExpect(testName, shouldBeShowing, shouldClose, cb) {
|
||||||
|
var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref);
|
||||||
|
if (!shouldBeShowing && !timeoutSec) {
|
||||||
|
timeoutSec = Services.prefs.getIntPref(timeoutPref);
|
||||||
|
}
|
||||||
|
hanguiOperation(testName, timeoutSec, shouldBeShowing, shouldClose, HANGUIOP_NOTHING, 0, false, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hanguiContinue(testName, check, cb) {
|
||||||
|
var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref);
|
||||||
|
hanguiOperation(testName, timeoutSec, true, true, HANGUIOP_COMMAND, IDC_CONTINUE, check, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hanguiStop(testName, check, cb) {
|
||||||
|
var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref);
|
||||||
|
hanguiOperation(testName, timeoutSec, true, true, HANGUIOP_COMMAND, IDC_STOP, check, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hanguiCancel(testName, cb) {
|
||||||
|
var timeoutSec = Services.prefs.getIntPref(hangUITimeoutPref);
|
||||||
|
hanguiOperation(testName, timeoutSec, true, true, HANGUIOP_CANCEL, 0, false, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest() {
|
||||||
|
if (obsCount > 0) {
|
||||||
|
os.removeObserver(testObserver, "plugin-crashed");
|
||||||
|
--obsCount;
|
||||||
|
}
|
||||||
|
SpecialPowers.clearUserPref(hangUITimeoutPref);
|
||||||
|
SpecialPowers.clearUserPref(hangUIMinDisplayPref);
|
||||||
|
SpecialPowers.clearUserPref(timeoutPref);
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
if (!SimpleTest.testPluginIsOOP()) {
|
||||||
|
ok(true, "Skipping this test when test plugin is not OOP.");
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
resetVars();
|
||||||
|
|
||||||
|
hanguiExpect("Prime ChromeWorker", false, false, "test1");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.frameLoaded = runTests;
|
||||||
|
|
||||||
|
var obsCount = 0;
|
||||||
|
|
||||||
|
function onPluginCrashedHangUI(aEvent) {
|
||||||
|
ok(true, "Plugin crashed notification received");
|
||||||
|
is(aEvent.type, "PluginCrashed", "event is correct type");
|
||||||
|
|
||||||
|
is(p, aEvent.target, "Plugin crashed event target is plugin element");
|
||||||
|
|
||||||
|
ok(aEvent instanceof Components.interfaces.nsIDOMDataContainerEvent,
|
||||||
|
"plugin crashed event has the right interface");
|
||||||
|
|
||||||
|
var minidumpID = aEvent.getData("minidumpID");
|
||||||
|
isnot(minidumpID, "", "got a non-empty dump ID");
|
||||||
|
var pluginName = aEvent.getData("pluginName");
|
||||||
|
is(pluginName, "Test Plug-in", "got correct plugin name");
|
||||||
|
var pluginFilename = aEvent.getData("pluginFilename");
|
||||||
|
isnot(pluginFilename, "", "got a non-empty filename");
|
||||||
|
var didReport = aEvent.getData("submittedCrashReport");
|
||||||
|
// The app itself may or may not have decided to submit the report, so
|
||||||
|
// allow either true or false here.
|
||||||
|
ok((didReport == true || didReport == false), "event said crash report was submitted");
|
||||||
|
os.removeObserver(testObserver, "plugin-crashed");
|
||||||
|
--obsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetVars() {
|
||||||
|
iframe = document.getElementById('iframe1');
|
||||||
|
p = iframe.contentDocument.getElementById("plugin1");
|
||||||
|
if (obsCount == 0) {
|
||||||
|
os.addObserver(testObserver, "plugin-crashed", true);
|
||||||
|
++obsCount;
|
||||||
|
}
|
||||||
|
iframe.contentDocument.addEventListener("PluginCrashed",
|
||||||
|
onPluginCrashedHangUI,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test9b() {
|
||||||
|
hanguiExpect("test9b: Plugin Hang UI is not showing (checkbox)", false);
|
||||||
|
p.stall(STALL_DURATION);
|
||||||
|
hanguiExpect("test9b: Plugin Hang UI is still not showing (checkbox)", false, false, "finishTest");
|
||||||
|
p.stall(STALL_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test9a() {
|
||||||
|
resetVars();
|
||||||
|
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
||||||
|
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
|
||||||
|
SpecialPowers.setIntPref(timeoutPref, 45);
|
||||||
|
hanguiContinue("test9a: Continue button works with checkbox", true, "test9b");
|
||||||
|
p.stall(STALL_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test9() {
|
||||||
|
window.frameLoaded = test9a;
|
||||||
|
iframe.contentWindow.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test8a() {
|
||||||
|
resetVars();
|
||||||
|
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
||||||
|
SpecialPowers.setIntPref(hangUIMinDisplayPref, 4);
|
||||||
|
hanguiExpect("test8a: Plugin Hang UI is not showing (disabled due to hangUIMinDisplaySecs)", false, false, "test9");
|
||||||
|
var exceptionThrown = false;
|
||||||
|
try {
|
||||||
|
p.hang();
|
||||||
|
} catch(e) {
|
||||||
|
exceptionThrown = true;
|
||||||
|
}
|
||||||
|
ok(exceptionThrown, "test8a: Exception thrown from hang() when plugin was terminated");
|
||||||
|
}
|
||||||
|
|
||||||
|
function test8() {
|
||||||
|
window.frameLoaded = test8a;
|
||||||
|
iframe.contentWindow.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test7a() {
|
||||||
|
resetVars();
|
||||||
|
SpecialPowers.setIntPref(hangUITimeoutPref, 0);
|
||||||
|
hanguiExpect("test7a: Plugin Hang UI is not showing (disabled)", false, false, "test8");
|
||||||
|
var exceptionThrown = false;
|
||||||
|
try {
|
||||||
|
p.hang();
|
||||||
|
} catch(e) {
|
||||||
|
exceptionThrown = true;
|
||||||
|
}
|
||||||
|
ok(exceptionThrown, "test7a: Exception thrown from hang() when plugin was terminated");
|
||||||
|
}
|
||||||
|
|
||||||
|
function test7() {
|
||||||
|
window.frameLoaded = test7a;
|
||||||
|
iframe.contentWindow.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test6() {
|
||||||
|
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
||||||
|
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
|
||||||
|
SpecialPowers.setIntPref(timeoutPref, 3);
|
||||||
|
hanguiExpect("test6: Plugin Hang UI is showing", true, true, "test7");
|
||||||
|
var exceptionThrown = false;
|
||||||
|
try {
|
||||||
|
p.hang();
|
||||||
|
} catch(e) {
|
||||||
|
exceptionThrown = true;
|
||||||
|
}
|
||||||
|
ok(exceptionThrown, "test6: Exception thrown from hang() when plugin was terminated (child timeout)");
|
||||||
|
}
|
||||||
|
|
||||||
|
function test5a() {
|
||||||
|
resetVars();
|
||||||
|
hanguiCancel("test5a: Close button works", "test6");
|
||||||
|
p.stall(STALL_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test5() {
|
||||||
|
window.frameLoaded = test5a;
|
||||||
|
iframe.contentWindow.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test4() {
|
||||||
|
hanguiStop("test4: Stop button works", false);
|
||||||
|
// We'll get an exception here because the plugin was terminated
|
||||||
|
var exceptionThrown = false;
|
||||||
|
try {
|
||||||
|
p.hang();
|
||||||
|
} catch(e) {
|
||||||
|
exceptionThrown = true;
|
||||||
|
}
|
||||||
|
ok(exceptionThrown, "test4: Exception thrown from hang() when plugin was terminated");
|
||||||
|
SimpleTest.executeSoon(test5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test3() {
|
||||||
|
hanguiContinue("test3: Continue button works", false, "test4");
|
||||||
|
p.stall(STALL_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test2() {
|
||||||
|
// This test is identical to test1 because there were some bugs where the
|
||||||
|
// Hang UI would show on the first hang but not on subsequent hangs
|
||||||
|
hanguiExpect("test2: Plugin Hang UI is showing", true, true, "test3");
|
||||||
|
p.stall(STALL_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test1() {
|
||||||
|
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
|
||||||
|
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
|
||||||
|
SpecialPowers.setIntPref(timeoutPref, 45);
|
||||||
|
hanguiExpect("test1: Plugin Hang UI is showing", true, true, "test2");
|
||||||
|
p.stall(STALL_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</script>
|
||||||
|
</window>
|
|
@ -147,6 +147,7 @@ static bool getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCoun
|
||||||
static bool asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
|
static bool stallPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
static bool reinitWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
static bool reinitWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||||
|
@ -210,6 +211,7 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||||
"asyncCallbackTest",
|
"asyncCallbackTest",
|
||||||
"checkGCRace",
|
"checkGCRace",
|
||||||
"hang",
|
"hang",
|
||||||
|
"stall",
|
||||||
"getClipboardText",
|
"getClipboardText",
|
||||||
"callOnDestroy",
|
"callOnDestroy",
|
||||||
"reinitWidget",
|
"reinitWidget",
|
||||||
|
@ -274,6 +276,7 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
|
||||||
asyncCallbackTest,
|
asyncCallbackTest,
|
||||||
checkGCRace,
|
checkGCRace,
|
||||||
hangPlugin,
|
hangPlugin,
|
||||||
|
stallPlugin,
|
||||||
getClipboardText,
|
getClipboardText,
|
||||||
callOnDestroy,
|
callOnDestroy,
|
||||||
reinitWidget,
|
reinitWidget,
|
||||||
|
@ -3314,6 +3317,24 @@ hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
stallPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||||
|
NPVariant* result)
|
||||||
|
{
|
||||||
|
uint32_t stallTimeSeconds = 0;
|
||||||
|
if ((argCount == 1) && NPVARIANT_IS_INT32(args[0])) {
|
||||||
|
stallTimeSeconds = (uint32_t) NPVARIANT_TO_INT32(args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
Sleep(stallTimeSeconds * 1000U);
|
||||||
|
#else
|
||||||
|
sleep(stallTimeSeconds);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_GTK)
|
#if defined(MOZ_WIDGET_GTK)
|
||||||
bool
|
bool
|
||||||
getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче