mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
Bug 1009760 - Support displaying of crash notification for GMP plugins. r=gfritzsche
This commit is contained in:
parent
3ee4babba1
commit
ffffc2cf45
@ -276,6 +276,14 @@ var gPluginHandler = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventType == "PluginCrashed" &&
|
||||
!(event.target instanceof Ci.nsIObjectLoadingContent)) {
|
||||
// If the event target is not a plugin object (i.e., an <object> or
|
||||
// <embed> element), this call is for a window-global plugin.
|
||||
this.pluginInstanceCrashed(event.target, event);
|
||||
return;
|
||||
}
|
||||
|
||||
let plugin = event.target;
|
||||
let doc = plugin.ownerDocument;
|
||||
|
||||
@ -1143,7 +1151,7 @@ var gPluginHandler = {
|
||||
|
||||
// Crashed-plugin event listener. Called for every instance of a
|
||||
// plugin in content.
|
||||
pluginInstanceCrashed: function (plugin, aEvent) {
|
||||
pluginInstanceCrashed: function (target, aEvent) {
|
||||
// Ensure the plugin and event are of the right type.
|
||||
if (!(aEvent instanceof Ci.nsIDOMCustomEvent))
|
||||
return;
|
||||
@ -1161,18 +1169,22 @@ var gPluginHandler = {
|
||||
|
||||
let messageString = gNavigatorBundle.getFormattedString("crashedpluginsMessage.title", [pluginName]);
|
||||
|
||||
//
|
||||
// Configure the crashed-plugin placeholder.
|
||||
//
|
||||
let plugin = null, doc;
|
||||
if (target instanceof Ci.nsIObjectLoadingContent) {
|
||||
plugin = target;
|
||||
doc = plugin.ownerDocument;
|
||||
} else {
|
||||
doc = target.document;
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
// doPrompt is specific to the crashed plugin overlay, and
|
||||
// therefore is not applicable for window-global plugins.
|
||||
doPrompt = false;
|
||||
}
|
||||
|
||||
// Force a layout flush so the binding is attached.
|
||||
plugin.clientTop;
|
||||
let overlay = this.getPluginUI(plugin, "main");
|
||||
let statusDiv = this.getPluginUI(plugin, "submitStatus");
|
||||
let doc = plugin.ownerDocument;
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
let status;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// Determine which message to show regarding crash reports.
|
||||
if (submittedReport) { // submitReports && !doPrompt, handled in observer
|
||||
status = "submitted";
|
||||
@ -1180,31 +1192,15 @@ var gPluginHandler = {
|
||||
else if (!submitReports && !doPrompt) {
|
||||
status = "noSubmit";
|
||||
}
|
||||
else { // doPrompt
|
||||
else if (!pluginDumpID) {
|
||||
// If we don't have a minidumpID, we can't (or didn't) submit anything.
|
||||
// This can happen if the plugin is killed from the task manager.
|
||||
status = "noReport";
|
||||
}
|
||||
else {
|
||||
status = "please";
|
||||
this.getPluginUI(plugin, "submitButton").addEventListener("click",
|
||||
function (event) {
|
||||
if (event.button != 0 || !event.isTrusted)
|
||||
return;
|
||||
this.submitReport(pluginDumpID, browserDumpID, plugin);
|
||||
pref.setBoolPref("", optInCB.checked);
|
||||
}.bind(this));
|
||||
let optInCB = this.getPluginUI(plugin, "submitURLOptIn");
|
||||
let pref = Services.prefs.getBranch("dom.ipc.plugins.reportCrashURL");
|
||||
optInCB.checked = pref.getBoolPref("");
|
||||
}
|
||||
|
||||
// If we don't have a minidumpID, we can't (or didn't) submit anything.
|
||||
// This can happen if the plugin is killed from the task manager.
|
||||
if (!pluginDumpID) {
|
||||
status = "noReport";
|
||||
}
|
||||
|
||||
statusDiv.setAttribute("status", status);
|
||||
|
||||
let helpIcon = this.getPluginUI(plugin, "helpIcon");
|
||||
this.addLinkClickCallback(helpIcon, "openHelpPage");
|
||||
|
||||
// If we're showing the link to manually trigger report submission, we'll
|
||||
// want to be able to update all the instances of the UI for this crash to
|
||||
// show an updated message when a report is submitted.
|
||||
@ -1238,26 +1234,15 @@ var gPluginHandler = {
|
||||
}
|
||||
#endif
|
||||
|
||||
let crashText = this.getPluginUI(plugin, "crashedText");
|
||||
crashText.textContent = messageString;
|
||||
|
||||
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
|
||||
|
||||
let link = this.getPluginUI(plugin, "reloadLink");
|
||||
this.addLinkClickCallback(link, "reloadPage", browser);
|
||||
|
||||
let notificationBox = gBrowser.getNotificationBox(browser);
|
||||
let isShowing = false;
|
||||
|
||||
let isShowing = this.shouldShowOverlay(plugin, overlay);
|
||||
|
||||
// Is the <object>'s size too small to hold what we want to show?
|
||||
if (!isShowing) {
|
||||
// First try hiding the crash report submission UI.
|
||||
statusDiv.removeAttribute("status");
|
||||
|
||||
isShowing = this.shouldShowOverlay(plugin, overlay);
|
||||
if (plugin) {
|
||||
// If there's no plugin (an <object> or <embed> element), this call is
|
||||
// for a window-global plugin. In this case, there's no overlay to show.
|
||||
isShowing = _setUpPluginOverlay.call(this, plugin, doPrompt, browser);
|
||||
}
|
||||
this.setVisibility(plugin, overlay, isShowing);
|
||||
|
||||
if (isShowing) {
|
||||
// If a previous plugin on the page was too small and resulted in adding a
|
||||
@ -1330,5 +1315,54 @@ var gPluginHandler = {
|
||||
}, false);
|
||||
}
|
||||
|
||||
// Configure the crashed-plugin placeholder.
|
||||
// Returns true if the plugin overlay is visible.
|
||||
function _setUpPluginOverlay(plugin, doPromptSubmit, browser) {
|
||||
if (!plugin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Force a layout flush so the binding is attached.
|
||||
plugin.clientTop;
|
||||
let overlay = this.getPluginUI(plugin, "main");
|
||||
let statusDiv = this.getPluginUI(plugin, "submitStatus");
|
||||
|
||||
if (doPromptSubmit) {
|
||||
this.getPluginUI(plugin, "submitButton").addEventListener("click",
|
||||
function (event) {
|
||||
if (event.button != 0 || !event.isTrusted)
|
||||
return;
|
||||
this.submitReport(pluginDumpID, browserDumpID, plugin);
|
||||
pref.setBoolPref("", optInCB.checked);
|
||||
}.bind(this));
|
||||
let optInCB = this.getPluginUI(plugin, "submitURLOptIn");
|
||||
let pref = Services.prefs.getBranch("dom.ipc.plugins.reportCrashURL");
|
||||
optInCB.checked = pref.getBoolPref("");
|
||||
}
|
||||
|
||||
statusDiv.setAttribute("status", status);
|
||||
|
||||
let helpIcon = this.getPluginUI(plugin, "helpIcon");
|
||||
this.addLinkClickCallback(helpIcon, "openHelpPage");
|
||||
|
||||
let crashText = this.getPluginUI(plugin, "crashedText");
|
||||
crashText.textContent = messageString;
|
||||
|
||||
let link = this.getPluginUI(plugin, "reloadLink");
|
||||
this.addLinkClickCallback(link, "reloadPage", browser);
|
||||
|
||||
let isShowing = this.shouldShowOverlay(plugin, overlay);
|
||||
|
||||
// Is the <object>'s size too small to hold what we want to show?
|
||||
if (!isShowing) {
|
||||
// First try hiding the crash report submission UI.
|
||||
statusDiv.removeAttribute("status");
|
||||
|
||||
isShowing = this.shouldShowOverlay(plugin, overlay);
|
||||
}
|
||||
this.setVisibility(plugin, overlay, isShowing);
|
||||
|
||||
return isShowing;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -62,6 +62,7 @@ run-if = crashreporter
|
||||
[browser_CTP_notificationBar.js]
|
||||
[browser_CTP_outsideScrollArea.js]
|
||||
[browser_CTP_resize.js]
|
||||
[browser_globalplugin_crashinfobar.js]
|
||||
[browser_pageInfo_plugins.js]
|
||||
[browser_pluginnotification.js]
|
||||
[browser_pluginplaypreview.js]
|
||||
|
@ -0,0 +1,69 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
let gTestBrowser = null;
|
||||
|
||||
let propBagProperties = {
|
||||
pluginName: "GlobalTestPlugin",
|
||||
pluginDumpID: "1234",
|
||||
browserDumpID: "5678",
|
||||
submittedCrashReport: false
|
||||
}
|
||||
|
||||
// Test that plugin crash submissions still work properly after
|
||||
// click-to-play activation.
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
let tab = gBrowser.loadOneTab("about:blank", { inBackground: false });
|
||||
gTestBrowser = gBrowser.getBrowserForTab(tab);
|
||||
gTestBrowser.addEventListener("PluginCrashed", onCrash, false);
|
||||
gTestBrowser.addEventListener("load", onPageLoad, true);
|
||||
|
||||
registerCleanupFunction(function cleanUp() {
|
||||
gTestBrowser.removeEventListener("PluginCrashed", onCrash, false);
|
||||
gTestBrowser.removeEventListener("load", onPageLoad, true);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
}
|
||||
|
||||
function onPageLoad() {
|
||||
executeSoon(generateCrashEvent);
|
||||
}
|
||||
|
||||
function generateCrashEvent() {
|
||||
let window = gTestBrowser.contentWindow;
|
||||
let propBag = Cc["@mozilla.org/hash-property-bag;1"]
|
||||
.createInstance(Ci.nsIWritablePropertyBag);
|
||||
for (let [name, val] of Iterator(propBagProperties)) {
|
||||
propBag.setProperty(name, val);
|
||||
}
|
||||
|
||||
let event = window.document.createEvent("CustomEvent");
|
||||
event.initCustomEvent("PluginCrashed", true, true, propBag);
|
||||
window.dispatchEvent(event);
|
||||
}
|
||||
|
||||
|
||||
function onCrash(event) {
|
||||
let target = event.target;
|
||||
is (target, gTestBrowser.contentWindow, "Event target is the window.");
|
||||
|
||||
let propBag = event.detail.QueryInterface(Ci.nsIPropertyBag2);
|
||||
for (let [name, val] of Iterator(propBagProperties)) {
|
||||
let type = typeof val;
|
||||
let propVal = type == "string"
|
||||
? propBag.getPropertyAsAString(name)
|
||||
: propBag.getPropertyAsBool(name);
|
||||
is (propVal, val, "Correct property in detail propBag: " + name + ".");
|
||||
}
|
||||
|
||||
let notificationBox = gBrowser.getNotificationBox(gTestBrowser);
|
||||
let notification = notificationBox.getNotificationWithValue("plugin-crashed");
|
||||
|
||||
ok(notification, "Infobar was shown.");
|
||||
is(notification.priority, notificationBox.PRIORITY_WARNING_MEDIUM, "Correct priority.");
|
||||
is(notification.getAttribute("label"), "The GlobalTestPlugin plugin has crashed.", "Correct message.");
|
||||
finish();
|
||||
}
|
Loading…
Reference in New Issue
Block a user