Bug 1508942 - Remove more plugins code; disable plugins by content policy. r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 28 Nov 2018 10:29:36 +1300
changeset 33799 61f67f491dd7c5c1e80be45aeadb3d5cbba37978
parent 33798 d01f1963d14968aeffa96a43c22715edc9fab90a
child 33800 48522dae2fd481e1e7e6b62d82f3e724c47637ee
push id388
push userclokep@gmail.com
push dateMon, 28 Jan 2019 20:54:56 +0000
reviewersmkmelin
bugs1508942
Bug 1508942 - Remove more plugins code; disable plugins by content policy. r=mkmelin
mail/app/profile/all-thunderbird.js
mail/base/content/extensionsOverlay.css
mail/components/about-support/content/aboutSupport.xhtml
mail/components/preferences/actionsshared.js
mail/components/preferences/applications.js
mail/locales/en-US/chrome/messenger/messenger.properties
mail/locales/en-US/chrome/messenger/preferences/preferences.properties
mail/testsuite-targets.mk
mail/themes/linux/mail/preferences/applications.css
mail/themes/osx/mail/preferences/applications.css
mail/themes/windows/mail/preferences/applications.css
mailnews/base/src/nsMsgContentPolicy.cpp
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -246,19 +246,16 @@ pref("browser.preferences.instantApply",
 pref("browser.preferences.instantApply", true);
 #endif
 #ifdef XP_MACOSX
 pref("browser.preferences.animateFadeIn", true);
 #else
 pref("browser.preferences.animateFadeIn", false);
 #endif
 
-pref("browser.download.show_plugins_in_list", false);
-pref("browser.download.hide_plugins_without_extensions", true);
-
 pref("accessibility.typeaheadfind", false);
 pref("accessibility.typeaheadfind.timeout", 5000);
 pref("accessibility.typeaheadfind.linksonly", false);
 pref("accessibility.typeaheadfind.flashBar", 1);
 
 pref("mail.close_message_window.on_delete", false);
 
 // Number of lines of To/CC/BCC address headers to show before "more"
@@ -379,17 +376,17 @@ pref("network.protocol-handler.warn-exte
 pref("network.protocol-handler.warn-external.https", false);
 pref("network.protocol-handler.warn-external.ftp", false);
 
 pref("network.hosts.smtp_server",           "mail");
 pref("network.hosts.pop_server",            "mail");
 
 // Temporarily add 'preferences' and 'newserror' to the list of about: pages that do not have a CSP specified.
 // The list should be kept in sync with the one in m-c/modules/libpref/init/all.js. See bug 1495983.
-pref("csp.about_uris_without_csp", "preferences,newserror,blank,printpreview,srcdoc,about,addons,cache-entry,config,crashes,debugging,devtools,downloads,home,memory,networking,newtab,performance,plugins,policies,profiles,restartrequired,searchreset,serviceworkers,sessionrestore,support,sync-log,telemetry,url-classifier,webrtc,welcomeback");
+pref("csp.about_uris_without_csp", "preferences,newserror,blank,printpreview,srcdoc,about,addons,cache-entry,config,crashes,debugging,devtools,downloads,home,memory,networking,newtab,performance,policies,profiles,restartrequired,searchreset,serviceworkers,sessionrestore,support,sync-log,telemetry,url-classifier,webrtc,welcomeback");
 
 pref("security.warn_entering_secure", false);
 pref("security.warn_entering_weak", false);
 pref("security.warn_leaving_secure", false);
 pref("security.warn_viewing_mixed", false);
 
 pref("general.config.obscure_value", 0); // for MCD .cfg files
 
@@ -707,76 +704,16 @@ pref("places.frecency.permRedirectVisitB
 pref("places.frecency.tempRedirectVisitBonus", 0);
 pref("places.frecency.reloadVisitBonus", 0);
 pref("places.frecency.defaultVisitBonus", 0);
 
 // bonus (in percent) for place types for frecency calculations
 pref("places.frecency.unvisitedBookmarkBonus", 140);
 pref("places.frecency.unvisitedTypedBonus", 200);
 
-// The default for this pref reflects whether the build is capable of IPC.
-// (Turning it on in a no-IPC build will have no effect.)
-#ifdef XP_MACOSX
-// i386 ipc preferences
-pref("dom.ipc.plugins.enabled.i386", false);
-pref("dom.ipc.plugins.enabled.i386.flash player.plugin", true);
-pref("dom.ipc.plugins.enabled.i386.javaplugin2_npapi.plugin", true);
-pref("dom.ipc.plugins.enabled.i386.javaappletplugin.plugin", true);
-// x86_64 ipc preferences
-pref("dom.ipc.plugins.enabled.x86_64", true);
-#else
-pref("dom.ipc.plugins.enabled", true);
-#endif
-
-// This pref governs whether we attempt to work around problems caused by
-// plugins using OS calls to manipulate the cursor while running out-of-
-// process.  These workarounds all involve intercepting (hooking) certain
-// OS calls in the plugin process, then arranging to make certain OS calls
-// in the browser process.  Eventually plugins will be required to use the
-// NPAPI to manipulate the cursor, and these workarounds will be removed.
-// See bug 621117.
-#ifdef XP_MACOSX
-pref("dom.ipc.plugins.nativeCursorSupport", true);
-#endif
-
-// Refer to bug 1509297 for details. For now, we disable the new UA widget to make tests pass.
-pref("dom.ua_widget.enabled", false);
-
-// plugin finder service url
-pref("pfs.datasource.url", "https://pfs.mozilla.org/plugins/PluginFinderService.
-php?mimetype=%PLUGIN_MIMETYPE%&appID=%APP_ID%&appVersion=%APP_VERSION%&clientOS=
-%CLIENT_OS%&chromeLocale=%CHROME_LOCALE%&appRelease=%APP_RELEASE%");
-
-// By default we show an infobar message when pages require plugins that are
-// outdated.
-pref("plugins.hide_infobar_for_outdated_plugin", false);
-
-#ifdef XP_MACOSX
-pref("plugins.use_layers", false);
-pref("plugins.hide_infobar_for_carbon_failure_plugin", false);
-#endif
-
-pref("plugins.update.url", "https://www.mozilla.org/%LOCALE%/plugincheck/");
-pref("plugins.update.notifyUser", false);
-pref("plugins.crash.supportUrl", "https://live.thunderbird.net/%APP%/plugin-crashed?locale=%LOCALE%&version=%VERSION%&os=%OS%&buildid=%APPBUILDID%");
-
-// Click-to-play has not been ported for TB yet, see bug 814168.
-// The default plugin state should be changed to "ask to activate" when this
-// has been done.
-pref("plugins.click_to_play", false);
-// Disable by default.
-pref("plugin.default.state", 0);
-
-// Plugins bundled in XPIs are enabled by default.
-pref("plugin.defaultXpi.state", 2);
-
-// Flash is enabled and Java is disabled by default.
-pref("plugin.state.flash", 2);
-pref("plugin.state.java", 0);
-
 // Windows taskbar support
 #ifdef XP_WIN
 pref("mail.taskbar.lists.enabled", true);
 pref("mail.taskbar.lists.tasks.enabled", true);
 #endif
 
 // Disable hardware accelerated layers
 pref("layers.acceleration.disabled", true);
--- a/mail/base/content/extensionsOverlay.css
+++ b/mail/base/content/extensionsOverlay.css
@@ -23,11 +23,15 @@
   width: 664px;
   padding: 4px;
 }
 
 #tb-legacy-extensions-notice > .alert > description {
   margin: 0;
 }
 
+#category-plugin {
+  display: none;
+}
+
 .addon[status="installed"] {
   -moz-binding: url("chrome://messenger/content/extensions.xml#thunderbird-addon-generic");
 }
--- a/mail/components/about-support/content/aboutSupport.xhtml
+++ b/mail/components/about-support/content/aboutSupport.xhtml
@@ -193,26 +193,16 @@
                </button>
                <span id="profile-dir-box">
                </span>
             </td>
           </tr>
 
           <tr class="no-copy">
             <th class="column">
-              &aboutSupport.appBasicsEnabledPlugins;
-            </th>
-
-            <td>
-              <a href="about:plugins" target="_blank">about:plugins</a>
-            </td>
-          </tr>
-
-          <tr class="no-copy">
-            <th class="column">
               &aboutSupport.appBasicsBuildConfig;
             </th>
 
             <td>
               <a href="about:buildconfig" target="_blank">about:buildconfig</a>
             </td>
           </tr>
 
--- a/mail/components/preferences/actionsshared.js
+++ b/mail/components/preferences/actionsshared.js
@@ -2,29 +2,25 @@
  * 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 FILEACTION_SAVE_TO_DISK     = 1;
 var FILEACTION_OPEN_INTERNALLY  = 2;
 var FILEACTION_OPEN_DEFAULT     = 3;
 var FILEACTION_OPEN_CUSTOM      = 4;
-var FILEACTION_OPEN_PLUGIN      = 5;
 function FileAction() {
 }
 FileAction.prototype = {
   type: "",
   extension: "",
   hasExtension: true,
   editable: true,
   smallIcon: "",
   bigIcon: "",
   typeName: "",
   action: "",
   mimeInfo: null,
   customHandler: "",
   handleMode: false,
-  pluginAvailable: false,
-  pluginEnabled: false,
-  handledOnlyByPlugin: false,
 };
 
 
--- a/mail/components/preferences/applications.js
+++ b/mail/components/preferences/applications.js
@@ -6,30 +6,17 @@
 // applications.inc.xul
 /* globals ICON_URL_APP */
 // mail/base/content/contentAreaClick.js
 /* globals openLinkExternally */
 
 // ------------------------------
 // Constants & Enumeration Values
 
-var PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
-
-// Preferences that affect which entries to show in the list.
-var PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
-var PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
-  "browser.download.hide_plugins_without_extensions";
-
-// The nsHandlerInfoAction enumeration values in nsIHandlerInfo identify
-// the actions the application can take with content of various types.
-// But since nsIHandlerInfo doesn't support plugins, there's no value
-// identifying the "use plugin" action, so we use this constant instead.
-var kActionUsePlugin = 5;
-
-// For CSS. Can be one of "ask", "save", "plugin" or "feed". If absent, the icon URL
+// For CSS. Can be one of "ask", "save", or "feed". If absent, the icon URL
 // was set by us to a custom handler icon and CSS should not try to override it.
 var APP_ICON_ATTR_NAME = "appHandlerIcon";
 
 var gNodeToObjectMap = new WeakMap();
 
 // CloudFile account tools used by gCloudFileTab.
 ChromeUtils.import("resource:///modules/cloudFileAccounts.js");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
@@ -119,47 +106,26 @@ class HandlerListItem {
 
 /**
  * This object wraps nsIHandlerInfo with some additional functionality
  * the Applications prefpane needs to display and allow modification of
  * the list of handled types.
  *
  * We create an instance of this wrapper for each entry we might display
  * in the prefpane, and we compose the instances from various sources,
- * including navigator.plugins and the handler service.
+ * including the handler service.
  *
  * We don't implement all the original nsIHandlerInfo functionality,
  * just the stuff that the prefpane needs.
  */
 class HandlerInfoWrapper {
   constructor(type, handlerInfo) {
     this.type = type;
     this.wrappedHandlerInfo = handlerInfo;
     this.disambiguateDescription = false;
-
-    // A plugin that can handle this type, if any.
-    //
-    // Note: just because we have one doesn't mean it *will* handle the type.
-    // That depends on whether or not the type is in the list of types for which
-    // plugin handling is disabled.
-    this.pluginName = "";
-
-    // Whether or not this type is only handled by a plugin or is also handled
-    // by some user-configured action as specified in the handler info object.
-    //
-    // Note: we can't just check if there's a handler info object for this type,
-    // because OS and user configuration is mixed up in the handler info object,
-    // so we always need to retrieve it for the OS info and can't tell whether
-    // it represents only OS-default information or user-configured information.
-    //
-    // FIXME: once handler info records are broken up into OS-provided records
-    // and user-configured records, stop using this boolean flag and simply
-    // check for the presence of a user-configured record to determine whether
-    // or not this type is only handled by a plugin.  Filed as bug 395142.
-    this.handledOnlyByPlugin = false;
   }
 
   get description() {
     if (this.wrappedHandlerInfo.description)
       return this.wrappedHandlerInfo.description;
 
     if (this.primaryExtension) {
       var extension = this.primaryExtension.toUpperCase();
@@ -228,20 +194,16 @@ class HandlerInfoWrapper {
       // Is it because the app can't actually do that?  But if that's true,
       // then why would a preferredAction ever get set to this value
       // in the first place?
 
       case Ci.nsIHandlerInfo.useSystemDefault:
         return gApplicationsPane._prefsBundle.getFormattedString("useDefault",
           [this.defaultDescription]);
 
-      case kActionUsePlugin:
-        return gApplicationsPane._prefsBundle.getFormattedString("usePluginIn",
-          [this.pluginName,
-          gApplicationsPane._brandShortName]);
       default:
         throw new Error(`Unexpected preferredAction: ${this.preferredAction}`);
     }
   }
 
   get actionIconClass() {
     if (this.alwaysAskBeforeHandling) {
       return "ask";
@@ -250,19 +212,16 @@ class HandlerInfoWrapper {
     switch (this.preferredAction) {
       case Ci.nsIHandlerInfo.saveToDisk:
         return "save";
 
       case Ci.nsIHandlerInfo.handleInternally:
         if (this instanceof InternalHandlerInfoWrapper) {
           return "ask";
         }
-
-      case kActionUsePlugin:
-        return "plugin";
     }
 
     return "";
   }
 
   get actionIcon() {
     switch (this.preferredAction) {
       case Ci.nsIHandlerInfo.useSystemDefault:
@@ -351,20 +310,16 @@ class HandlerInfoWrapper {
   }
 
   get defaultDescription() {
     return this.wrappedHandlerInfo.defaultDescription;
   }
 
   // What to do with content of this type.
   get preferredAction() {
-    // If we have an enabled plugin, then the action is to use that plugin.
-    if (this.plugin && !this.isDisabledPluginType)
-      return kActionUsePlugin;
-
     // If the action is to use a helper app, but we don't have a preferred
     // handler app, then switch to using the system default, if any; otherwise
     // fall back to saving to disk, which is the default action in nsMIMEInfo.
     // Note: "save to disk" is an invalid value for protocol info objects,
     // but the alwaysAskBeforeHandling getter will detect that situation
     // and always return true in that case to override this invalid value.
     if (this.wrappedHandlerInfo.preferredAction ==
           Ci.nsIHandlerInfo.useHelperApp &&
@@ -373,34 +328,20 @@ class HandlerInfoWrapper {
         return Ci.nsIHandlerInfo.useSystemDefault;
       return Ci.nsIHandlerInfo.saveToDisk;
     }
 
     return this.wrappedHandlerInfo.preferredAction;
   }
 
   set preferredAction(aNewValue) {
-    // We don't modify the preferred action if the new action is to use a plugin
-    // because handler info objects don't understand our custom "use plugin"
-    // value.  Also, leaving it untouched means that we can automatically revert
-    // to the old setting if the user ever removes the plugin.
-
-    if (aNewValue != kActionUsePlugin)
-      this.wrappedHandlerInfo.preferredAction = aNewValue;
+    this.wrappedHandlerInfo.preferredAction = aNewValue;
   }
 
   get alwaysAskBeforeHandling() {
-    // If this type is handled only by a plugin, we can't trust the value
-    // in the handler info object, since it'll be a default based on the absence
-    // of any user configuration, and the default in that case is to always ask,
-    // even though we never ask for content handled by a plugin, so special case
-    // plugin-handled types by returning false here.
-    if (this.plugin && this.handledOnlyByPlugin)
-      return false;
-
     // If this is a protocol type and the preferred action is "save to disk",
     // which is invalid for such types, then return true here to override that
     // action.  This could happen when the preferred action is to use a helper
     // app, but the preferredApplicationHandler is invalid, and there isn't
     // a default handler, so the preferredAction getter returns save to disk
     // instead.
     if (!(this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) &&
         this.preferredAction == Ci.nsIHandlerInfo.saveToDisk)
@@ -409,78 +350,26 @@ class HandlerInfoWrapper {
     return this.wrappedHandlerInfo.alwaysAskBeforeHandling;
   }
 
   set alwaysAskBeforeHandling(aNewValue) {
     this.wrappedHandlerInfo.alwaysAskBeforeHandling = aNewValue;
   }
 
   // The primary file extension associated with this type, if any.
-  //
-  // XXX Plugin objects contain an array of MimeType objects with "suffixes"
-  // properties; if this object has an associated plugin, shouldn't we check
-  // those properties for an extension?
   get primaryExtension() {
     try {
       if (this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo &&
           this.wrappedHandlerInfo.primaryExtension)
         return this.wrappedHandlerInfo.primaryExtension;
     } catch (ex) {}
 
     return null;
   }
 
-  get isDisabledPluginType() {
-    return this._getDisabledPluginTypes().includes(this.type);
-  }
-
-  _getDisabledPluginTypes() {
-    var types = "";
-
-    if (Services.prefs.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES))
-      types = Services.prefs.getCharPref(PREF_DISABLED_PLUGIN_TYPES);
-
-    // Only split if the string isn't empty so we don't end up with an array
-    // containing a single empty string.
-    if (types != "")
-      return types.split(",");
-
-    return [];
-  }
-
-  disablePluginType() {
-    var disabledPluginTypes = this._getDisabledPluginTypes();
-
-    if (!disabledPluginTypes.includes(this.type))
-      disabledPluginTypes.push(this.type);
-
-    Services.prefs.setCharPref(PREF_DISABLED_PLUGIN_TYPES,
-                               disabledPluginTypes.join(","));
-
-    // Update the category manager so existing browser windows update.
-    Services.catMan.deleteCategoryEntry("Gecko-Content-Viewers", this.type, false);
-  }
-
-  enablePluginType() {
-    var disabledPluginTypes = this._getDisabledPluginTypes();
-
-    var type = this.type;
-    disabledPluginTypes = disabledPluginTypes.filter(v => v != type);
-
-    Services.prefs.setCharPref(PREF_DISABLED_PLUGIN_TYPES,
-                               disabledPluginTypes.join(","));
-
-    // Update the category manager so existing browser windows update.
-    Services.catMan.addCategoryEntry(
-      "Gecko-Content-Viewers", this.type,
-      "@mozilla.org/content/plugin/document-loader-factory;1",
-      false, true
-    );
-  }
-
   // -------
   // Storage
 
   store() {
     gHandlerService.store(this.wrappedHandlerInfo);
   }
 
   remove() {
@@ -905,24 +794,16 @@ var gApplicationsPane = {
   init() {
     // Initialize shortcuts to some commonly accessed elements & values.
     this._brandShortName =
       document.getElementById("bundleBrand").getString("brandShortName");
     this._prefsBundle = document.getElementById("bundlePreferences");
     this._list = document.getElementById("handlersView");
     this._filter = document.getElementById("filter");
 
-    // Observe preferences that influence what we display so we can rebuild
-    // the view when they change.
-    Services.prefs.addObserver(PREF_SHOW_PLUGINS_IN_LIST, this);
-    Services.prefs.addObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this);
-
-    // Listen for window unload so we can remove our preference observers.
-    window.addEventListener("unload", this, {capture: false, once: true});
-
     // Figure out how we should be sorting the list.  We persist sort settings
     // across sessions, so we can't assume the default sort column/direction.
     // XXX should we be using the XUL sort service instead?
     this._sortColumn = document.getElementById("typeColumn");
     if (document.getElementById("actionColumn").hasAttribute("sortDirection")) {
       this._sortColumn = document.getElementById("actionColumn");
       // The typeColumn element always has a sortDirection attribute,
       // either because it was persisted or because the default value
@@ -944,155 +825,54 @@ var gApplicationsPane = {
       self.rebuildView();
 
       // Notify observers that the UI is now ready
       Services.obs.notifyObservers(window, "app-handler-pane-loaded");
     };
     setTimeout(_delayedPaneLoad, 0, this);
   },
 
-  destroy() {
-    Services.prefs.removeObserver(PREF_SHOW_PLUGINS_IN_LIST, this);
-    Services.prefs.removeObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this);
-  },
-
-  // -----------
-  // nsISupports
-
-  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
-
-  // -----------
-  // nsIObserver
-
-  observe(aSubject, aTopic, aData) {
-    // Rebuild the list when there are changes to preferences that influence
-    // whether or not to show certain entries in the list.
-    if (aTopic == "nsPref:changed" && !this._storingAction) {
-      // These two prefs alter the list of visible types, so we have to rebuild
-      // that list when they change.
-      if (aData == PREF_SHOW_PLUGINS_IN_LIST ||
-          aData == PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS) {
-        this._rebuildVisibleTypes();
-        this._sortVisibleTypes();
-      }
-
-      // All the prefs we observe can affect what we display, so we rebuild
-      // the view when any of them changes.
-      this.rebuildView();
-    }
-  },
-
-  // -------------
-  // EventListener
-
-  handleEvent(aEvent) {
-    if (aEvent.type == "unload")
-      this.destroy();
-  },
-
   // ---------------------------
   // Composed Model Construction
 
   _loadData() {
-    this._loadPluginHandlers();
     this._loadApplicationHandlers();
   },
 
   /**
-   * Load the set of handlers defined by plugins.
-   *
-   * Note: if there's more than one plugin for a given MIME type, we assume
-   * the last one is the one that the application will use.  That may not be
-   * correct, but it's how we've been doing it for years.
-   *
-   * Perhaps we should instead query navigator.mimeTypes for the set of types
-   * supported by the application and then get the plugin from each MIME type's
-   * enabledPlugin property.  But if there's a plugin for a type, we need
-   * to know about it even if it isn't enabled, since we're going to give
-   * the user an option to enable it.
-   *
-   * Also note that enabledPlugin does not get updated when
-   * plugin.disable_full_page_plugin_for_types changes, so even if we could use
-   * enabledPlugin to get the plugin that would be used, we'd still need to
-   * check the pref ourselves to find out if it's enabled.
-   */
-  _loadPluginHandlers() {
-    "use strict";
-
-    let mimeTypes = navigator.mimeTypes;
-
-    for (let mimeType of mimeTypes) {
-      let handlerInfoWrapper;
-      if (mimeType.type in this._handledTypes) {
-        handlerInfoWrapper = this._handledTypes[mimeType.type];
-      } else {
-        let wrappedHandlerInfo =
-          gMIMEService.getFromTypeAndExtension(mimeType.type, null);
-        handlerInfoWrapper = new HandlerInfoWrapper(mimeType.type, wrappedHandlerInfo);
-        handlerInfoWrapper.handledOnlyByPlugin = true;
-        this._handledTypes[mimeType.type] = handlerInfoWrapper;
-      }
-      handlerInfoWrapper.pluginName = mimeType.enabledPlugin.name;
-    }
-  },
-
-  /**
    * Load the set of handlers defined by the application datastore.
    */
   _loadApplicationHandlers() {
     var wrappedHandlerInfos = gHandlerService.enumerate();
     while (wrappedHandlerInfos.hasMoreElements()) {
       let wrappedHandlerInfo =
         wrappedHandlerInfos.getNext().QueryInterface(Ci.nsIHandlerInfo);
       let type = wrappedHandlerInfo.type;
 
       let handlerInfoWrapper;
       if (type in this._handledTypes) {
         handlerInfoWrapper = this._handledTypes[type];
       } else {
         handlerInfoWrapper = new HandlerInfoWrapper(type, wrappedHandlerInfo);
         this._handledTypes[type] = handlerInfoWrapper;
       }
-
-      handlerInfoWrapper.handledOnlyByPlugin = false;
     }
   },
 
   // -----------------
   // View Construction
 
   _rebuildVisibleTypes() {
     // Reset the list of visible types and the visible type description.
     this._visibleTypes.length = 0;
     this._visibleDescriptions.clear();
 
-    // Get the preferences that help determine what types to show.
-    var showPlugins = Services.prefs.getBoolPref(PREF_SHOW_PLUGINS_IN_LIST);
-    var hidePluginsWithoutExtensions =
-      Services.prefs.getBoolPref(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS);
-
     for (let type in this._handledTypes) {
       let handlerInfo = this._handledTypes[type];
 
-      // Hide plugins without associated extensions if so prefed so we don't
-      // show a whole bunch of obscure types handled by plugins on Mac.
-      // Note: though protocol types don't have extensions, we still show them;
-      // the pref is only meant to be applied to MIME types, since plugins are
-      // only associated with MIME types.
-      // FIXME: should we also check the "suffixes" property of the plugin?
-      // Filed as bug 395135.
-      if (hidePluginsWithoutExtensions && handlerInfo.handledOnlyByPlugin &&
-          handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo &&
-          !handlerInfo.primaryExtension)
-        continue;
-
-      // Hide types handled only by plugins if so prefed.
-      if (handlerInfo.handledOnlyByPlugin && !showPlugins)
-        continue;
-
       // We couldn't find any reason to exclude the type, so include it.
       this._visibleTypes.push(handlerInfo);
 
       let otherHandlerInfo = this._visibleDescriptions
                                  .get(handlerInfo.description);
       if (!otherHandlerInfo) {
         // This is the first type with this description that we encountered
         // while rebuilding the _visibleTypes array this time. Make sure the
@@ -1293,29 +1073,16 @@ var gApplicationsPane = {
       // Attach the handler app object to the menu item so we can use it
       // to make changes to the datastore when the user selects the item.
       menuItem.handlerApp = possibleApp;
 
       menuPopup.appendChild(menuItem);
       possibleAppMenuItems.push(menuItem);
     }
 
-    // Create a menu item for the plugin.
-    if (handlerInfo.plugin) {
-      var pluginMenuItem = document.createElement("menuitem");
-      pluginMenuItem.setAttribute("action", kActionUsePlugin);
-      let label = this._prefsBundle.getFormattedString("usePluginIn",
-                                                       [handlerInfo.plugin.name,
-                                                        this._brandShortName]);
-      pluginMenuItem.setAttribute("label", label);
-      pluginMenuItem.setAttribute("tooltiptext", label);
-      pluginMenuItem.setAttribute(APP_ICON_ATTR_NAME, "plugin");
-      menuPopup.appendChild(pluginMenuItem);
-    }
-
     // Create a menu item for selecting a local application.
     let createItem = true;
     if (AppConstants.platform == "win") {
       // On Windows, selecting an application to open another application
       // would be meaningless so we special case executables.
       var executableType = Cc["@mozilla.org/mime;1"]
                              .getService(Ci.nsIMIMEService)
                              .getTypeFromExtension("exe");
@@ -1359,19 +1126,16 @@ var gApplicationsPane = {
       case Ci.nsIHandlerInfo.useSystemDefault:
         menu.selectedItem = defaultMenuItem;
         break;
       case Ci.nsIHandlerInfo.useHelperApp:
         if (preferredApp)
           menu.selectedItem =
             possibleAppMenuItems.filter(v => v.handlerApp.equals(preferredApp))[0];
         break;
-      case kActionUsePlugin:
-        menu.selectedItem = pluginMenuItem;
-        break;
       case Ci.nsIHandlerInfo.saveToDisk:
         menu.selectedItem = saveMenuItem;
         break;
     }
     // menu.selectedItem may be null if the preferredAction is
     // useSystemDefault, but handlerInfo.hasDefaultHandler returns false.
     // For now, we'll just use the askMenuItem to avoid ugly exceptions.
     menu.previousSelectedItem = menu.selectedItem || askMenuItem;
@@ -1469,22 +1233,16 @@ var gApplicationsPane = {
     var typeItem = this._list.selectedItem;
     var handlerInfo = this._handledTypes[typeItem.type];
 
     if (aActionItem.hasAttribute("alwaysAsk")) {
       handlerInfo.alwaysAskBeforeHandling = true;
     } else if (aActionItem.hasAttribute("action")) {
       let action = parseInt(aActionItem.getAttribute("action"));
 
-      // Set the plugin state if we're enabling or disabling a plugin.
-      if (action == kActionUsePlugin)
-        handlerInfo.enablePluginType();
-      else if (handlerInfo.plugin && !handlerInfo.isDisabledPluginType)
-        handlerInfo.disablePluginType();
-
       // Set the preferred application handler.
       // We leave the existing preferred app in the list when we set
       // the preferred action to something other than useHelperApp so that
       // legacy datastores that don't have the preferred app in the list
       // of possible apps still include the preferred app in the list of apps
       // the user can choose to handle the type.
       if (action == Ci.nsIHandlerInfo.useHelperApp)
         handlerInfo.preferredApplicationHandler = aActionItem.handlerApp;
@@ -1493,20 +1251,16 @@ var gApplicationsPane = {
       handlerInfo.alwaysAskBeforeHandling = false;
 
       // Set the preferred action.
       handlerInfo.preferredAction = action;
     }
 
     handlerInfo.store();
 
-    // Make sure the handler info object is flagged to indicate that there is
-    // now some user configuration for the type.
-    handlerInfo.handledOnlyByPlugin = false;
-
     // Update the action label and image to reflect the new preferred action.
     HandlerListItem.forNode(typeItem).refreshAction();
   },
 
   manageApp(aEvent) {
     // Don't let the normal "on select action" handler get this event,
     // as we handle it specially ourselves.
     aEvent.stopPropagation();
--- a/mail/locales/en-US/chrome/messenger/messenger.properties
+++ b/mail/locales/en-US/chrome/messenger/messenger.properties
@@ -724,34 +724,16 @@ safeModeRestartPromptTitle=Restart with 
 safeModeRestartPromptMessage=Are you sure you want to disable all add-ons and restart?
 safeModeRestartButton=Restart
 
 # LOCALIZATION NOTE (downloadAndInstallButton.label): %S is replaced by the
 # version of the update: "Update to 28.0".
 update.downloadAndInstallButton.label=Update to %S
 update.downloadAndInstallButton.accesskey=U
 
-outdatedpluginsMessage.title=Some plugins used by this page are out of date.
-outdatedpluginsMessage.updateButton.label=Update Plugins…
-outdatedpluginsMessage.updateButton.accesskey=U
-blockedpluginsMessage.title=Some plugins required by this page have been blocked for your protection.
-blockedpluginsMessage.infoButton.label=Details…
-blockedpluginsMessage.infoButton.accesskey=D
-blockedpluginsMessage.searchButton.label=Update Plugins…
-blockedpluginsMessage.searchButton.accesskey=U
-crashedpluginsMessage.title=The %S plugin has crashed.
-crashedpluginsMessage.reloadButton.label=Reload page
-crashedpluginsMessage.reloadButton.accesskey=R
-crashedpluginsMessage.submitButton.label=Submit a crash report
-crashedpluginsMessage.submitButton.accesskey=S
-crashedpluginsMessage.learnMore=Learn More…
-carbonFailurePluginsMessage.message=This page asks to use a plugin that can only run in 32-bit mode
-carbonFailurePluginsMessage.restartButton.label=Restart in 32-bit mode
-carbonFailurePluginsMessage.restartButton.accesskey=R
-
 # Sanitize
 # LOCALIZATION NOTE (sanitizeDialog2.everything.title): When "Time range to
 # clear" is set to "Everything", the Clear Recent History dialog's title is
 # changed to this.  See UI mockup and comment 11 at bug 480169 -->
 sanitizeDialog2.everything.title=Clear All History
 sanitizeButtonOK=Clear Now
 # LOCALIZATION NOTE (sanitizeEverythingWarning2): Warning that appears when
 # "Time range to clear" is set to "Everything" in Clear Recent History dialog,
--- a/mail/locales/en-US/chrome/messenger/preferences/preferences.properties
+++ b/mail/locales/en-US/chrome/messenger/preferences/preferences.properties
@@ -33,21 +33,16 @@ useDefault=Use %S (default)
 useOtherApp=Use other…
 fpTitleChooseApp=Select Helper Application
 manageApp=Application Details…
 alwaysAsk=Always ask
 delete=Delete Action
 confirmDeleteTitle=Delete Action
 confirmDeleteText=Are you sure you want to delete this action?
 
-# LOCALIZATION NOTE (usePluginIn):
-# %1$S = plugin name (for example "QuickTime Plugin-in 7.2")
-# %2$S = brandShortName from brand.properties (for example "Shredder")
-usePluginIn=Use %1$S (in %2$S)
-
 # LOCALIZATION NOTE (typeDescriptionWithDetails):
 # %1$S = type description (for example "Portable Document Format")
 # %2$S = details (see below, for example "(application/pdf: .pdf, .pdfx)")
 typeDescriptionWithDetails=%1$S %2$S
 
 # LOCALIZATION NOTE (typeDetailsWithTypeOrExt):
 # %1$S = type or extensions (for example "application/pdf", or ".pdf, .pdfx")
 typeDetailsWithTypeOrExt=(%1$S)
--- a/mail/testsuite-targets.mk
+++ b/mail/testsuite-targets.mk
@@ -28,28 +28,26 @@ find-solo-test = $(if $(and $(SOLO_TEST)
 # PYTHONHOME messes very badly with virtualenv setups, so unset it.
 mozmill:
 	$(call check-no-solo,SOLOVAR is specified. Perhaps you meant mozmill-one.)
 	unset PYTHONHOME && cd $(MOZMILLDIR) && MACOSX_DEPLOYMENT_TARGET= \
 	$(MOZMILLPYTHON) runtestlist.py --list=mozmilltests.list \
 	--binary=$(abspath $(BINARY)) \
 	--dir=$(commtopsrcdir)/mail/test/mozmill \
 	--symbols-path=$(ABS_DIST)/crashreporter-symbols \
-	--plugins-path=$(ABS_DIST)/plugins \
 	--testing-modules-dir=$(topobjdir)/_tests/modules \
 	$(MOZMILL_EXTRA)
 
 mozmill-one: solo-test = $(find-solo-test)
 mozmill-one:
 	unset PYTHONHOME && cd $(MOZMILLDIR) && MACOSX_DEPLOYMENT_TARGET= \
 	$(MOZMILLPYTHON) runtest.py \
 	--test=$(commtopsrcdir)/mail/test/mozmill/$(solo-test) \
 	--binary=$(abspath $(BINARY)) \
 	--symbols-path=$(ABS_DIST)/crashreporter-symbols \
-	--plugins-path=$(ABS_DIST)/plugins \
 	--testing-modules-dir=$(topobjdir)/_tests/modules \
 	$(MOZMILL_EXTRA)
 
 # We need to add the mozmill tests to the package for tests.
 # If Lightning is enabled, also stage the lightning extension
 ifdef MOZ_CALENDAR
 package-tests: stage-calendar
 else
--- a/mail/themes/linux/mail/preferences/applications.css
+++ b/mail/themes/linux/mail/preferences/applications.css
@@ -30,21 +30,16 @@ menuitem[appHandlerIcon="ask"] {
   list-style-image: url("chrome://messenger/skin/preferences/alwaysAsk.png");
 }
 
 richlistitem[appHandlerIcon="save"],
 menuitem[appHandlerIcon="save"] {
   list-style-image: url("moz-icon://stock/gtk-save?size=menu");
 }
 
-richlistitem[appHandlerIcon="plugin"],
-menuitem[appHandlerIcon="plugin"] {
-  list-style-image: url("chrome://global/skin/plugins/pluginGeneric.svg");
-}
-
 .actionsMenu .menulist-icon {
   margin-inline-end: 1px;
   height: 16px;
   width: 16px;
 }
 
 .actionsMenu > menupopup > menuitem > .menu-iconic-left {
   padding-inline-start: 0;
--- a/mail/themes/osx/mail/preferences/applications.css
+++ b/mail/themes/osx/mail/preferences/applications.css
@@ -33,21 +33,16 @@ menuitem[appHandlerIcon="ask"] {
   list-style-image: url("chrome://messenger/skin/preferences/alwaysAsk.png");
 }
 
 richlistitem[appHandlerIcon="save"],
 menuitem[appHandlerIcon="save"] {
   list-style-image: url("chrome://messenger/skin/preferences/saveFile.png");
 }
 
-richlistitem[appHandlerIcon="plugin"],
-menuitem[appHandlerIcon="plugin"] {
-  list-style-image: url("chrome://global/skin/plugins/pluginGeneric.svg");
-}
-
 .actionsMenu .menulist-icon {
   margin-inline-end: 1px;
 }
 
 .actionsMenu > menupopup > menuitem > .menu-iconic-left {
   padding-inline-start: 3px;
   padding-inline-end: 1px;
 }
--- a/mail/themes/windows/mail/preferences/applications.css
+++ b/mail/themes/windows/mail/preferences/applications.css
@@ -34,21 +34,16 @@ menuitem[appHandlerIcon="ask"] {
   list-style-image: url("chrome://messenger/skin/preferences/alwaysAsk.png");
 }
 
 richlistitem[appHandlerIcon="save"],
 menuitem[appHandlerIcon="save"] {
   list-style-image: url("chrome://messenger/skin/preferences/saveFile.png");
 }
 
-richlistitem[appHandlerIcon="plugin"],
-menuitem[appHandlerIcon="plugin"] {
-  list-style-image: url("chrome://global/skin/plugins/pluginGeneric.svg");
-}
-
 .actionsMenu .menulist-icon {
   margin-inline-end: 3px;
 }
 
 .actionsMenu > menupopup > menuitem > .menu-iconic-left {
   padding-inline-start: 0px;
   padding-inline-end: 2px;
 }
--- a/mailnews/base/src/nsMsgContentPolicy.cpp
+++ b/mailnews/base/src/nsMsgContentPolicy.cpp
@@ -855,36 +855,35 @@ nsresult nsMsgContentPolicy::SetDisableI
   }
 
   if (!isAllowedContent) {
     // Disable JavaScript on message URLs.
     rv = docShell->SetAllowJavascript(false);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = docShell->SetAllowContentRetargetingOnChildren(false);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = docShell->SetAllowPlugins(false);
-    NS_ENSURE_SUCCESS(rv, rv);
 
     uint32_t sandboxFlags;
     rv = docShell->GetSandboxFlags(&sandboxFlags);
     sandboxFlags |= SANDBOXED_FORMS;
     NS_ENSURE_SUCCESS(rv, rv);
     rv = docShell->SetSandboxFlags(sandboxFlags);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
-    // JavaScript and plugins are allowed on non-message URLs.
+    // JavaScript is allowed on non-message URLs.
     rv = docShell->SetAllowJavascript(true);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = docShell->SetAllowContentRetargetingOnChildren(true);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = docShell->SetAllowPlugins(true);
-    NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  rv = docShell->SetAllowPlugins(false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   return NS_OK;
 }
 
 /**
  * Gets the root docshell from a requesting context.
  */
 nsresult
 nsMsgContentPolicy::GetRootDocShellForContext(nsISupports *aRequestingContext,
@@ -1022,31 +1021,28 @@ nsMsgContentPolicy::OnLocationChange(nsI
 
   nsCOMPtr<nsIMsgMessageUrl> messageUrl = do_QueryInterface(aLocation, &rv);
   mozilla::Unused << messageUrl;
   if (NS_SUCCEEDED(rv)) {
     // Disable javascript on message URLs.
     rv = docShell->SetAllowJavascript(false);
     NS_ASSERTION(NS_SUCCEEDED(rv),
                  "Failed to set javascript disabled on docShell");
-    // Also disable plugins if the preference requires it.
-    rv = docShell->SetAllowPlugins(false);
-    NS_ASSERTION(NS_SUCCEEDED(rv),
-                 "Failed to set plugins disabled on docShell");
   }
   else {
-    // Disable javascript and plugins are allowed on non-message URLs.
+    // Javascript is allowed on non-message URLs. Plugins are not.
     rv = docShell->SetAllowJavascript(true);
     NS_ASSERTION(NS_SUCCEEDED(rv),
                  "Failed to set javascript allowed on docShell");
-    rv = docShell->SetAllowPlugins(true);
-    NS_ASSERTION(NS_SUCCEEDED(rv),
-                 "Failed to set plugins allowed on docShell");
   }
 
+  rv = docShell->SetAllowPlugins(false);
+  NS_ASSERTION(NS_SUCCEEDED(rv),
+               "Failed to set plugins disabled on docShell");
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMsgContentPolicy::OnStatusChange(nsIWebProgress *aWebProgress,
                                    nsIRequest *aRequest, nsresult aStatus,
                                    const char16_t *aMessage)
 {