summaryrefslogtreecommitdiffstats
path: root/browser/base/content/browser-plugins.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/browser-plugins.js')
-rw-r--r--browser/base/content/browser-plugins.js516
1 files changed, 0 insertions, 516 deletions
diff --git a/browser/base/content/browser-plugins.js b/browser/base/content/browser-plugins.js
deleted file mode 100644
index c1bc65860..000000000
--- a/browser/base/content/browser-plugins.js
+++ /dev/null
@@ -1,516 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * 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/. */
-
-var gPluginHandler = {
- PREF_SESSION_PERSIST_MINUTES: "plugin.sessionPermissionNow.intervalInMinutes",
- PREF_PERSISTENT_DAYS: "plugin.persistentPermissionAlways.intervalInDays",
- MESSAGES: [
- "PluginContent:ShowClickToPlayNotification",
- "PluginContent:RemoveNotification",
- "PluginContent:UpdateHiddenPluginUI",
- "PluginContent:HideNotificationBar",
- "PluginContent:InstallSinglePlugin",
- "PluginContent:ShowPluginCrashedNotification",
- "PluginContent:SubmitReport",
- "PluginContent:LinkClickCallback",
- ],
-
- init: function () {
- const mm = window.messageManager;
- for (let msg of this.MESSAGES) {
- mm.addMessageListener(msg, this);
- }
- window.addEventListener("unload", this);
- },
-
- uninit: function () {
- const mm = window.messageManager;
- for (let msg of this.MESSAGES) {
- mm.removeMessageListener(msg, this);
- }
- window.removeEventListener("unload", this);
- },
-
- handleEvent: function (event) {
- if (event.type == "unload") {
- this.uninit();
- }
- },
-
- receiveMessage: function (msg) {
- switch (msg.name) {
- case "PluginContent:ShowClickToPlayNotification":
- this.showClickToPlayNotification(msg.target, msg.data.plugins, msg.data.showNow,
- msg.principal, msg.data.location);
- break;
- case "PluginContent:RemoveNotification":
- this.removeNotification(msg.target, msg.data.name);
- break;
- case "PluginContent:UpdateHiddenPluginUI":
- this.updateHiddenPluginUI(msg.target, msg.data.haveInsecure, msg.data.actions,
- msg.principal, msg.data.location);
- break;
- case "PluginContent:HideNotificationBar":
- this.hideNotificationBar(msg.target, msg.data.name);
- break;
- case "PluginContent:InstallSinglePlugin":
- this.installSinglePlugin(msg.data.pluginInfo);
- break;
- case "PluginContent:ShowPluginCrashedNotification":
- this.showPluginCrashedNotification(msg.target, msg.data.messageString,
- msg.data.pluginID);
- break;
- case "PluginContent:SubmitReport":
- // Nothing to do here
- break;
- case "PluginContent:LinkClickCallback":
- switch (msg.data.name) {
- case "managePlugins":
- case "openHelpPage":
- case "openPluginUpdatePage":
- this[msg.data.name].call(this, msg.data.pluginTag);
- break;
- }
- break;
- default:
- Cu.reportError("gPluginHandler did not expect to handle message " + msg.name);
- break;
- }
- },
-
- // Callback for user clicking on a disabled plugin
- managePlugins: function () {
- BrowserOpenAddonsMgr("addons://list/plugin");
- },
-
- // Callback for user clicking on the link in a click-to-play plugin
- // (where the plugin has an update)
- openPluginUpdatePage: function(pluginTag) {
- let url = Services.blocklist.getPluginInfoURL(pluginTag);
- if (!url) {
- url = Services.blocklist.getPluginBlocklistURL(pluginTag);
- }
- openUILinkIn(url, "tab");
- },
-
- submitReport: function submitReport(runID, keyVals, submitURLOptIn) {
- /*** STUB ***/
- return;
- },
-
- // Callback for user clicking a "reload page" link
- reloadPage: function (browser) {
- browser.reload();
- },
-
- // Callback for user clicking the help icon
- openHelpPage: function () {
- openHelpLink("plugin-crashed", false);
- },
-
- _clickToPlayNotificationEventCallback: function PH_ctpEventCallback(event) {
- if (event == "showing") {
- Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_SHOWN")
- .add(!this.options.primaryPlugin);
- // Histograms always start at 0, even though our data starts at 1
- let histogramCount = this.options.pluginData.size - 1;
- if (histogramCount > 4) {
- histogramCount = 4;
- }
- Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_PLUGIN_COUNT")
- .add(histogramCount);
- }
- else if (event == "dismissed") {
- // Once the popup is dismissed, clicking the icon should show the full
- // list again
- this.options.primaryPlugin = null;
- }
- },
-
- /**
- * Called from the plugin doorhanger to set the new permissions for a plugin
- * and activate plugins if necessary.
- * aNewState should be either "allownow" "allowalways" or "block"
- */
- _updatePluginPermission: function (aNotification, aPluginInfo, aNewState) {
- let permission;
- let expireType;
- let expireTime;
- let histogram =
- Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_USER_ACTION");
-
- // Update the permission manager.
- // Also update the current state of pluginInfo.fallbackType so that
- // subsequent opening of the notification shows the current state.
- switch (aNewState) {
- case "allownow":
- permission = Ci.nsIPermissionManager.ALLOW_ACTION;
- expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
- expireTime = Date.now() + Services.prefs.getIntPref(this.PREF_SESSION_PERSIST_MINUTES) * 60 * 1000;
- histogram.add(0);
- aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE;
- break;
-
- case "allowalways":
- permission = Ci.nsIPermissionManager.ALLOW_ACTION;
- expireType = Ci.nsIPermissionManager.EXPIRE_TIME;
- expireTime = Date.now() +
- Services.prefs.getIntPref(this.PREF_PERSISTENT_DAYS) * 24 * 60 * 60 * 1000;
- histogram.add(1);
- aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE;
- break;
-
- case "block":
- permission = Ci.nsIPermissionManager.PROMPT_ACTION;
- expireType = Ci.nsIPermissionManager.EXPIRE_NEVER;
- expireTime = 0;
- histogram.add(2);
- switch (aPluginInfo.blocklistState) {
- case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
- aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE;
- break;
- case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
- aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
- break;
- default:
- aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY;
- }
- break;
-
- // In case a plugin has already been allowed in another tab, the "continue allowing" button
- // shouldn't change any permissions but should run the plugin-enablement code below.
- case "continue":
- aPluginInfo.fallbackType = Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE;
- break;
- default:
- Cu.reportError(Error("Unexpected plugin state: " + aNewState));
- return;
- }
-
- let browser = aNotification.browser;
- if (aNewState != "continue") {
- let principal = aNotification.options.principal;
- Services.perms.addFromPrincipal(principal, aPluginInfo.permissionString,
- permission, expireType, expireTime);
- aPluginInfo.pluginPermissionType = expireType;
- }
-
- browser.messageManager.sendAsyncMessage("BrowserPlugins:ActivatePlugins", {
- pluginInfo: aPluginInfo,
- newState: aNewState,
- });
- },
-
- showClickToPlayNotification: function (browser, plugins, showNow,
- principal, location) {
- // It is possible that we've received a message from the frame script to show
- // a click to play notification for a principal that no longer matches the one
- // that the browser's content now has assigned (ie, the browser has browsed away
- // after the message was sent, but before the message was received). In that case,
- // we should just ignore the message.
- if (!principal.equals(browser.contentPrincipal)) {
- return;
- }
-
- // Data URIs, when linked to from some page, inherit the principal of that
- // page. That means that we also need to compare the actual locations to
- // ensure we aren't getting a message from a Data URI that we're no longer
- // looking at.
- let receivedURI = BrowserUtils.makeURI(location);
- if (!browser.documentURI.equalsExceptRef(receivedURI)) {
- return;
- }
-
- let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
-
- // If this is a new notification, create a pluginData map, otherwise append
- let pluginData;
- if (notification) {
- pluginData = notification.options.pluginData;
- } else {
- pluginData = new Map();
- }
-
- for (var pluginInfo of plugins) {
- if (pluginData.has(pluginInfo.permissionString)) {
- continue;
- }
-
- // If a block contains an infoURL, we should always prefer that to the default
- // URL that we construct in-product, even for other blocklist types.
- let url = Services.blocklist.getPluginInfoURL(pluginInfo.pluginTag);
-
- if (pluginInfo.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
- if (!url) {
- url = Services.blocklist.getPluginBlocklistURL(pluginInfo.pluginTag);
- }
- }
- else {
- url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "clicktoplay";
- }
- pluginInfo.detailsLink = url;
-
- pluginData.set(pluginInfo.permissionString, pluginInfo);
- }
-
- let primaryPluginPermission = null;
- if (showNow) {
- primaryPluginPermission = plugins[0].permissionString;
- }
-
- if (notification) {
- // Don't modify the notification UI while it's on the screen, that would be
- // jumpy and might allow clickjacking.
- if (showNow) {
- notification.options.primaryPlugin = primaryPluginPermission;
- notification.reshow();
- browser.messageManager.sendAsyncMessage("BrowserPlugins:NotificationShown");
- }
- return;
- }
-
- let options = {
- dismissed: !showNow,
- eventCallback: this._clickToPlayNotificationEventCallback,
- primaryPlugin: primaryPluginPermission,
- pluginData: pluginData,
- principal: principal,
- };
- PopupNotifications.show(browser, "click-to-play-plugins",
- "", "plugins-notification-icon",
- null, null, options);
- browser.messageManager.sendAsyncMessage("BrowserPlugins:NotificationShown");
- },
-
- removeNotification: function (browser, name) {
- let notification = PopupNotifications.getNotification(name, browser);
- if (notification)
- PopupNotifications.remove(notification);
- },
-
- hideNotificationBar: function (browser, name) {
- let notificationBox = gBrowser.getNotificationBox(browser);
- let notification = notificationBox.getNotificationWithValue(name);
- if (notification)
- notificationBox.removeNotification(notification, true);
- },
-
- updateHiddenPluginUI: function (browser, haveInsecure, actions,
- principal, location) {
- let origin = principal.originNoSuffix;
-
- // It is possible that we've received a message from the frame script to show
- // the hidden plugin notification for a principal that no longer matches the one
- // that the browser's content now has assigned (ie, the browser has browsed away
- // after the message was sent, but before the message was received). In that case,
- // we should just ignore the message.
- if (!principal.equals(browser.contentPrincipal)) {
- return;
- }
-
- // Data URIs, when linked to from some page, inherit the principal of that
- // page. That means that we also need to compare the actual locations to
- // ensure we aren't getting a message from a Data URI that we're no longer
- // looking at.
- let receivedURI = BrowserUtils.makeURI(location);
- if (!browser.documentURI.equalsExceptRef(receivedURI)) {
- return;
- }
-
- // Set up the icon
- document.getElementById("plugins-notification-icon").classList.
- toggle("plugin-blocked", haveInsecure);
-
- // Now configure the notification bar
- let notificationBox = gBrowser.getNotificationBox(browser);
-
- function hideNotification() {
- let n = notificationBox.getNotificationWithValue("plugin-hidden");
- if (n) {
- notificationBox.removeNotification(n, true);
- }
- }
-
- // There are three different cases when showing an infobar:
- // 1. A single type of plugin is hidden on the page. Show the UI for that
- // plugin.
- // 2a. Multiple types of plugins are hidden on the page. Show the multi-UI
- // with the vulnerable styling.
- // 2b. Multiple types of plugins are hidden on the page, but none are
- // vulnerable. Show the nonvulnerable multi-UI.
- function showNotification() {
- let n = notificationBox.getNotificationWithValue("plugin-hidden");
- if (n) {
- // If something is already shown, just keep it
- return;
- }
-
- Services.telemetry.getHistogramById("PLUGINS_INFOBAR_SHOWN").
- add(true);
-
- let message;
- // Icons set directly cannot be manipulated using moz-image-region, so
- // we use CSS classes instead.
- let brand = document.getElementById("bundle_brand").getString("brandShortName");
-
- if (actions.length == 1) {
- let pluginInfo = actions[0];
- let pluginName = pluginInfo.pluginName;
-
- switch (pluginInfo.fallbackType) {
- case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
- message = gNavigatorBundle.getFormattedString(
- "pluginActivateNew.message",
- [pluginName, origin]);
- break;
- case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
- message = gNavigatorBundle.getFormattedString(
- "pluginActivateOutdated.message",
- [pluginName, origin, brand]);
- break;
- case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
- message = gNavigatorBundle.getFormattedString(
- "pluginActivateVulnerable.message",
- [pluginName, origin, brand]);
- }
- } else {
- // Multi-plugin
- message = gNavigatorBundle.getFormattedString(
- "pluginActivateMultiple.message", [origin]);
- }
-
- let buttons = [
- {
- label: gNavigatorBundle.getString("pluginContinueBlocking.label"),
- accessKey: gNavigatorBundle.getString("pluginContinueBlocking.accesskey"),
- callback: function() {
- Services.telemetry.getHistogramById("PLUGINS_INFOBAR_BLOCK").
- add(true);
-
- Services.perms.addFromPrincipal(principal,
- "plugin-hidden-notification",
- Services.perms.DENY_ACTION);
- }
- },
- {
- label: gNavigatorBundle.getString("pluginActivateTrigger.label"),
- accessKey: gNavigatorBundle.getString("pluginActivateTrigger.accesskey"),
- callback: function() {
- Services.telemetry.getHistogramById("PLUGINS_INFOBAR_ALLOW").
- add(true);
-
- let curNotification =
- PopupNotifications.getNotification("click-to-play-plugins",
- browser);
- if (curNotification) {
- curNotification.reshow();
- }
- }
- }
- ];
- n = notificationBox.
- appendNotification(message, "plugin-hidden", null,
- notificationBox.PRIORITY_INFO_HIGH, buttons);
- if (haveInsecure) {
- n.classList.add('pluginVulnerable');
- }
- }
-
- if (actions.length == 0) {
- hideNotification();
- } else {
- let notificationPermission = Services.perms.testPermissionFromPrincipal(
- principal, "plugin-hidden-notification");
- if (notificationPermission == Ci.nsIPermissionManager.DENY_ACTION) {
- hideNotification();
- } else {
- showNotification();
- }
- }
- },
-
- contextMenuCommand: function (browser, plugin, command) {
- browser.messageManager.sendAsyncMessage("BrowserPlugins:ContextMenuCommand",
- { command: command }, { plugin: plugin });
- },
-
- // Crashed-plugin observer. Notified once per plugin crash, before events
- // are dispatched to individual plugin instances.
- NPAPIPluginCrashed : function(subject, topic, data) {
- let propertyBag = subject;
- if (!(propertyBag instanceof Ci.nsIPropertyBag2) ||
- !(propertyBag instanceof Ci.nsIWritablePropertyBag2) ||
- !propertyBag.hasKey("runID") ||
- !propertyBag.hasKey("pluginName")) {
- Cu.reportError("A NPAPI plugin crashed, but the properties of this plugin " +
- "cannot be read.");
- return;
- }
-
- let runID = propertyBag.getPropertyAsUint32("runID");
- let uglyPluginName = propertyBag.getPropertyAsAString("pluginName");
- let pluginName = BrowserUtils.makeNicePluginName(uglyPluginName);
- let pluginDumpID = propertyBag.getPropertyAsAString("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.
- let state = "noSubmit";
-
- let mm = window.getGroupMessageManager("browsers");
- mm.broadcastAsyncMessage("BrowserPlugins:NPAPIPluginProcessCrashed",
- { pluginName, runID, state });
- },
-
- /**
- * Shows a plugin-crashed notification bar for a browser that has had an
- * invisiable NPAPI plugin crash, or a GMP plugin crash.
- *
- * @param browser
- * The browser to show the notification for.
- * @param messageString
- * The string to put in the notification bar
- * @param pluginID
- * The unique-per-process identifier for the NPAPI plugin or GMP.
- * For a GMP, this is the pluginID. For NPAPI plugins (where "pluginID"
- * means something different), this is the runID.
- */
- showPluginCrashedNotification: function (browser, messageString, pluginID) {
- // If there's already an existing notification bar, don't do anything.
- let notificationBox = gBrowser.getNotificationBox(browser);
- let notification = notificationBox.getNotificationWithValue("plugin-crashed");
- if (notification) {
- return;
- }
-
- // Configure the notification bar
- let priority = notificationBox.PRIORITY_WARNING_MEDIUM;
- let iconURL = "chrome://mozapps/skin/plugins/notifyPluginCrashed.png";
- let reloadLabel = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label");
- let reloadKey = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey");
-
- let buttons = [{
- label: reloadLabel,
- accessKey: reloadKey,
- popup: null,
- callback: function() { browser.reload(); },
- }];
-
- notification = notificationBox.appendNotification(messageString, "plugin-crashed",
- iconURL, priority, buttons);
-
- // Add the "learn more" link.
- let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- let link = notification.ownerDocument.createElementNS(XULNS, "label");
- link.className = "text-link";
- link.setAttribute("value", gNavigatorBundle.getString("crashedpluginsMessage.learnMore"));
- let crashurl = formatURL("app.support.baseURL", true);
- crashurl += "plugin-crashed-notificationbar";
- link.href = crashurl;
- let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
- description.appendChild(link);
- },
-};
-
-gPluginHandler.init();