1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
10 ChromeUtils.defineESModuleGetters(lazy, {
11 CrashSubmit: "resource://gre/modules/CrashSubmit.sys.mjs",
14 ChromeUtils.defineLazyGetter(lazy, "gNavigatorBundle", function () {
15 const url = "chrome://browser/locale/browser.properties";
16 return Services.strings.createBundle(url);
19 export const PluginManager = {
20 gmpCrashes: new Map(),
22 observe(subject, topic) {
24 case "gmp-plugin-crash":
25 this._registerGMPCrash(subject);
30 _registerGMPCrash(subject) {
31 let propertyBag = subject;
33 !(propertyBag instanceof Ci.nsIWritablePropertyBag2) ||
34 !propertyBag.hasKey("pluginID") ||
35 !propertyBag.hasKey("pluginDumpID") ||
36 !propertyBag.hasKey("pluginName")
38 console.error("PluginManager can not read plugin information.");
42 let pluginID = propertyBag.getPropertyAsUint32("pluginID");
43 let pluginDumpID = propertyBag.getPropertyAsAString("pluginDumpID");
44 let pluginName = propertyBag.getPropertyAsACString("pluginName");
46 this.gmpCrashes.set(pluginID, { pluginDumpID, pluginID, pluginName });
49 // Only the parent process gets the gmp-plugin-crash observer
50 // notification, so we need to inform any content processes that
51 // the GMP has crashed. This then fires PluginCrashed events in
52 // all the relevant windows, which will trigger child actors being
53 // created, which will contact us again, when we'll use the
54 // gmpCrashes collection to respond.
56 Services.ppmm.broadcastAsyncMessage("gmp-plugin-crash", {
64 * Submit a crash report for a crashed plugin.
66 * @param pluginCrashID
67 * An object with a pluginID.
69 * An object whose key-value pairs will be merged
70 * with the ".extra" file submitted with the report.
71 * The properties of htis object will override properties
72 * of the same name in the .extra file.
74 submitCrashReport(pluginCrashID, keyVals = {}) {
75 let report = this.getCrashReport(pluginCrashID);
78 `Could not find plugin dump IDs for ${JSON.stringify(pluginCrashID)}.` +
79 `It is possible that a report was already submitted.`
84 let { pluginDumpID } = report;
85 lazy.CrashSubmit.submit(
87 lazy.CrashSubmit.SUBMITTED_FROM_CRASH_TAB,
89 recordSubmission: true,
90 extraExtraKeyVals: keyVals,
94 this.gmpCrashes.delete(pluginCrashID.pluginID);
97 getCrashReport(pluginCrashID) {
98 return this.gmpCrashes.get(pluginCrashID.pluginID);
102 export class PluginParent extends JSWindowActorParent {
103 receiveMessage(msg) {
104 let browser = this.manager.rootFrameLoader.ownerElement;
106 case "PluginContent:ShowPluginCrashedNotification":
107 this.showPluginCrashedNotification(browser, msg.data.pluginCrashID);
112 "PluginParent did not expect to handle message ",
122 * Shows a plugin-crashed notification bar for a browser that has had a
126 * The browser to show the notification for.
127 * @param pluginCrashID
128 * The unique-per-process identifier for GMP.
130 showPluginCrashedNotification(browser, pluginCrashID) {
131 // If there's already an existing notification bar, don't do anything.
132 let notificationBox = browser.getTabBrowser().getNotificationBox(browser);
134 notificationBox.getNotificationWithValue("plugin-crashed");
136 let report = PluginManager.getCrashReport(pluginCrashID);
137 if (notification || !report) {
141 // Configure the notification bar
142 let priority = notificationBox.PRIORITY_WARNING_MEDIUM;
143 let iconURL = "chrome://global/skin/icons/plugin.svg";
144 let reloadLabel = lazy.gNavigatorBundle.GetStringFromName(
145 "crashedpluginsMessage.reloadButton.label"
147 let reloadKey = lazy.gNavigatorBundle.GetStringFromName(
148 "crashedpluginsMessage.reloadButton.accesskey"
154 accessKey: reloadKey,
162 if (AppConstants.MOZ_CRASHREPORTER) {
163 let submitLabel = lazy.gNavigatorBundle.GetStringFromName(
164 "crashedpluginsMessage.submitButton.label"
166 let submitKey = lazy.gNavigatorBundle.GetStringFromName(
167 "crashedpluginsMessage.submitButton.accesskey"
171 accessKey: submitKey,
174 PluginManager.submitCrashReport(pluginCrashID);
178 buttons.push(submitButton);
181 // Add the "learn more" link.
182 let learnMoreLink = {
183 supportPage: "plugin-crashed-notificationbar",
184 label: lazy.gNavigatorBundle.GetStringFromName(
185 "crashedpluginsMessage.learnMore"
188 buttons.push(learnMoreLink);
190 let messageString = lazy.gNavigatorBundle.formatStringFromName(
191 "crashedpluginsMessage.title",
194 notificationBox.appendNotification(
197 label: messageString,