diff options
Diffstat (limited to 'browser/base/content/browser-plugins.js')
-rw-r--r-- | browser/base/content/browser-plugins.js | 516 |
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(); |