Bug 1146955 - Dispatch PluginCrashed event in content process on GMP crash for PeerConnection. r=jesup.

Original patch by Brad Lassey <blassey@mozilla.com>.
This commit is contained in:
Brad Lassey 2015-04-27 15:44:36 -04:00
parent ead628b6ad
commit c8d6950522
2 changed files with 92 additions and 48 deletions

View File

@ -114,27 +114,68 @@ this.PluginCrashReporter = {
this.crashReports = new Map();
Services.obs.addObserver(this, "plugin-crashed", false);
Services.obs.addObserver(this, "gmp-plugin-crash", false);
Services.obs.addObserver(this, "profile-after-change", false);
},
uninit() {
Services.obs.removeObserver(this, "plugin-crashed", false);
Services.obs.removeObserver(this, "gmp-plugin-crash", false);
Services.obs.removeObserver(this, "profile-after-change", false);
this.initialized = false;
},
observe(subject, topic, data) {
if (topic != "plugin-crashed") {
return;
}
switch(topic) {
case "plugin-crashed": {
let propertyBag = subject;
if (!(propertyBag instanceof Ci.nsIPropertyBag2) ||
!(propertyBag instanceof Ci.nsIWritablePropertyBag2) ||
!propertyBag.hasKey("runID") ||
!propertyBag.hasKey("pluginDumpID")) {
Cu.reportError("PluginCrashReporter can not read plugin information.");
return;
}
let propertyBag = subject;
if (!(propertyBag instanceof Ci.nsIPropertyBag2) ||
!(propertyBag instanceof Ci.nsIWritablePropertyBag2) ||
!propertyBag.hasKey("runID") ||
!propertyBag.hasKey("pluginName")) {
Cu.reportError("PluginCrashReporter can not read plugin information.");
return;
}
let runID = propertyBag.getPropertyAsUint32("runID");
let pluginDumpID = propertyBag.getPropertyAsAString("pluginDumpID");
let browserDumpID = propertyBag.getPropertyAsAString("browserDumpID");
if (pluginDumpID) {
this.crashReports.set(runID, { pluginDumpID, browserDumpID });
}
break;
}
case "gmp-plugin-crash": {
let propertyBag = subject;
if (!(propertyBag instanceof Ci.nsIWritablePropertyBag2) ||
!propertyBag.hasKey("pluginID") ||
!propertyBag.hasKey("pluginDumpID") ||
!propertyBag.hasKey("pluginName")) {
Cu.reportError("PluginCrashReporter can not read plugin information.");
return;
}
let runID = propertyBag.getPropertyAsUint32("runID");
let pluginDumpID = propertyBag.getPropertyAsAString("pluginDumpID");
let browserDumpID = propertyBag.getPropertyAsAString("browserDumpID");
if (pluginDumpID) {
this.crashReports.set(runID, { pluginDumpID, browserDumpID });
let pluginID = propertyBag.getPropertyAsUint32("pluginID");
let pluginDumpID = propertyBag.getPropertyAsAString("pluginDumpID");
if (pluginDumpID) {
this.crashReports.set(pluginID, { pluginDumpID });
}
// Only the parent process gets the gmp-plugin-crash observer
// notification, so we need to inform any content processes that
// the GMP has crashed.
if (Cc["@mozilla.org/parentprocessmessagemanager;1"]) {
let pluginName = propertyBag.getPropertyAsAString("pluginName");
let mm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
mm.broadcastAsyncMessage("gmp-plugin-crash",
{ pluginName, pluginID });
}
break;
}
case "profile-after-change":
this.uninit();
break;
}
},
@ -194,14 +235,4 @@ this.PluginCrashReporter = {
hasCrashReport(runID) {
return this.crashReports.has(runID);
},
/**
* Deprecated mechanism for sending crash reports for GMPs. This
* should be removed when bug 1146955 is fixed.
*/
submitGMPCrashReport(pluginDumpID, browserDumpID) {
CrashSubmit.submit(pluginDumpID, { recordSubmission: true });
if (browserDumpID)
CrashSubmit.submit(browserDumpID);
},
};

View File

@ -45,9 +45,14 @@ function GlobalPCList() {
Services.obs.addObserver(this, "network:offline-about-to-go-offline", true);
Services.obs.addObserver(this, "network:offline-status-changed", true);
Services.obs.addObserver(this, "gmp-plugin-crash", true);
if (Cc["@mozilla.org/childprocessmessagemanager;1"]) {
let mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
mm.addMessageListener("gmp-plugin-crash", this);
}
}
GlobalPCList.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsIMessageListener,
Ci.nsISupportsWeakReference,
Ci.IPeerConnectionManager]),
classID: PC_MANAGER_CID,
@ -93,6 +98,31 @@ GlobalPCList.prototype = {
return this._list[winID] ? true : false;
},
handleGMPCrash: function(data) {
let broadcastPluginCrash = function(list, winID, pluginID, pluginName) {
if (list.hasOwnProperty(winID)) {
list[winID].forEach(function(pcref) {
let pc = pcref.get();
if (pc) {
pc._pc.pluginCrash(pluginID, pluginName);
}
});
}
};
// a plugin crashed; if it's associated with any of our PCs, fire an
// event to the DOM window
for (let winId in this._list) {
broadcastPluginCrash(this._list, winId, data.pluginID, data.pluginName);
}
},
receiveMessage: function(message) {
if (message.name == "gmp-plugin-crash") {
this.handleGMPCrash(message.data);
}
},
observe: function(subject, topic, data) {
let cleanupPcRef = function(pcref) {
let pc = pcref.get();
@ -110,17 +140,6 @@ GlobalPCList.prototype = {
}
};
let broadcastPluginCrash = function(list, winID, pluginID, name, crashReportID) {
if (list.hasOwnProperty(winID)) {
list[winID].forEach(function(pcref) {
let pc = pcref.get();
if (pc) {
pc._pc.pluginCrash(pluginID, name, crashReportID);
}
});
}
};
if (topic == "inner-window-destroyed") {
let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
cleanupWinId(this._list, winID);
@ -162,17 +181,11 @@ GlobalPCList.prototype = {
}
}
} else if (topic == "gmp-plugin-crash") {
// a plugin crashed; if it's associated with any of our PCs, fire an
// event to the DOM window
let sep = data.indexOf(' ');
let pluginId = data.slice(0, sep);
let rest = data.slice(sep+1);
// This presumes no spaces in the name!
sep = rest.indexOf(' ');
let name = rest.slice(0, sep);
let crashId = rest.slice(sep+1);
for (let winId in this._list) {
broadcastPluginCrash(this._list, winId, pluginId, name, crashId);
if (subject instanceof Ci.nsIWritablePropertyBag2) {
let pluginID = subject.getPropertyAsUint32("pluginID");
let pluginName = subject.getPropertyAsAString("pluginName");
let data = { pluginID, pluginName };
this.handleGMPCrash(data);
}
}
},