Bug 619652 - Display plugin file and mime types in Add-ons Manager. Part 1: Implementation. r=Unfocused
authorFrank Yan <fyan@mozilla.com>
Sat, 15 Sep 2012 17:17:32 -0500
changeset 110762 81e812a83e9becc5e8c3cc66d92a2e33fd312e2b
parent 110761 4807f1c1308ea664f334868bdd36dcf95da71630
child 110763 907385f76803514ac59444775177f9d059d9d77a
push id23716
push userryanvm@gmail.com
push dateSat, 20 Oct 2012 01:43:16 +0000
treeherdermozilla-central@ff4af83233dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs619652
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 619652 - Display plugin file and mime types in Add-ons Manager. Part 1: Implementation. r=Unfocused
toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
toolkit/mozapps/extensions/PluginProvider.jsm
toolkit/mozapps/extensions/content/extensions.css
toolkit/mozapps/extensions/content/pluginPrefs.xul
toolkit/mozapps/extensions/jar.mn
--- a/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
+++ b/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
@@ -51,8 +51,11 @@
 <!ENTITY reloadPlugin.post                                   " to try again.">
 <!-- LOCALIZATION NOTE (report.please): This and the other report.* strings should be as short as possible, ideally 2-3 words. -->
 <!ENTITY report.please                                       "Send crash report">
 <!ENTITY report.submitting                                   "Sending report…">
 <!ENTITY report.submitted                                    "Crash report sent.">
 <!ENTITY report.disabled                                     "Crash reporting disabled.">
 <!ENTITY report.failed                                       "Submission failed.">
 <!ENTITY report.unavailable                                  "No report available.">
+
+<!ENTITY plugin.file                                         "File">
+<!ENTITY plugin.mimeTypes                                    "MIME Types">
\ No newline at end of file
--- a/toolkit/mozapps/extensions/PluginProvider.jsm
+++ b/toolkit/mozapps/extensions/PluginProvider.jsm
@@ -10,24 +10,24 @@ const Ci = Components.interfaces;
 var EXPORTED_SYMBOLS = [];
 
 Components.utils.import("resource://gre/modules/AddonManager.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 const URI_EXTENSION_STRINGS  = "chrome://mozapps/locale/extensions/extensions.properties";
 const STRING_TYPE_NAME       = "type.%ID%.name";
 
-["LOG", "WARN", "ERROR"].forEach(function(aName) {
-  this.__defineGetter__(aName, function() {
+for (let name of ["LOG", "WARN", "ERROR"]) {
+  this.__defineGetter__(name, function() {
     Components.utils.import("resource://gre/modules/AddonLogging.jsm");
 
     LogManager.getLogger("addons.plugins", this);
-    return this[aName];
+    return this[name];
   });
-}, this);
+}
 
 function getIDHashForString(aStr) {
   // return the two-digit hexadecimal code for a byte
   function toHexString(charCode)
     ("0" + charCode.toString(16)).slice(-2);
 
   let hasher = Cc["@mozilla.org/security/hash;1"].
                createInstance(Ci.nsICryptoHash);
@@ -46,22 +46,45 @@ function getIDHashForString(aStr) {
                hash.substr(16, 4) + "-" +
                hash.substr(20) + "}";
 }
 
 var PluginProvider = {
   // A dictionary mapping IDs to names and descriptions
   plugins: null,
 
+  startup: function PL_startup() {
+    Services.obs.addObserver(this, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED, false);
+  },
+
   /**
    * Called when the application is shutting down. Only necessary for tests
    * to be able to simulate a shutdown.
    */
   shutdown: function PL_shutdown() {
     this.plugins = null;
+    Services.obs.removeObserver(this, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED);
+  },
+
+  observe: function(aSubject, aTopic, aData) {
+    this.getAddonByID(aData, function(plugin) {
+      if (!plugin)
+        return;
+
+      let libLabel = aSubject.getElementById("pluginLibraries");
+      libLabel.textContent = plugin.pluginLibraries.join(", ");
+
+      let typeLabel = aSubject.getElementById("pluginMimeTypes"), types = [];
+      for (let type of plugin.pluginMimeTypes) {
+        let extras = [type.description.trim(), type.suffixes].
+                     filter(function(x) x).join(": ");
+        types.push(type.type + (extras ? " (" + extras + ")" : ""));
+      }
+      typeLabel.textContent = types.join(",\n");
+    });
   },
 
   /**
    * Called to get an Addon with a particular ID.
    *
    * @param  aId
    *         The ID of the add-on to retrieve
    * @param  aCallback
@@ -137,35 +160,35 @@ var PluginProvider = {
 
   buildPluginList: function PL_buildPluginList() {
     let tags = Cc["@mozilla.org/plugin/host;1"].
                getService(Ci.nsIPluginHost).
                getPluginTags({});
 
     this.plugins = {};
     let plugins = {};
-    tags.forEach(function(aTag) {
-      if (!(aTag.name in plugins))
-        plugins[aTag.name] = {};
-      if (!(aTag.description in plugins[aTag.name])) {
+    for (let tag of tags) {
+      if (!(tag.name in plugins))
+        plugins[tag.name] = {};
+      if (!(tag.description in plugins[tag.name])) {
         let plugin = {
-          name: aTag.name,
-          description: aTag.description,
-          tags: [aTag]
+          name: tag.name,
+          description: tag.description,
+          tags: [tag]
         };
 
-        let id = getIDHashForString(aTag.name + aTag.description);
+        let id = getIDHashForString(tag.name + tag.description);
 
-        plugins[aTag.name][aTag.description] = plugin;
+        plugins[tag.name][tag.description] = plugin;
         this.plugins[id] = plugin;
       }
       else {
-        plugins[aTag.name][aTag.description].tags.push(aTag);
+        plugins[tag.name][tag.description].tags.push(tag);
       }
-    }, this);
+    }
   }
 };
 
 /**
  * The PluginWrapper wraps a set of nsIPluginTags to provide the data visible to
  * public callers through the API.
  */
 function PluginWrapper(aId, aName, aDescription, aTags) {
@@ -184,19 +207,18 @@ function PluginWrapper(aId, aName, aDesc
 
   this.__defineGetter__("isActive", function() !aTags[0].blocklisted && !aTags[0].disabled);
   this.__defineGetter__("appDisabled", function() aTags[0].blocklisted);
   this.__defineGetter__("userDisabled", function() aTags[0].disabled);
   this.__defineSetter__("userDisabled", function(aVal) {
     if (aTags[0].disabled == aVal)
       return;
 
-    aTags.forEach(function(aTag) {
-      aTag.disabled = aVal;
-    });
+    for (let tag of aTags)
+      tag.disabled = aVal;
     AddonManagerPrivate.callAddonListeners(aVal ? "onDisabling" : "onEnabling", this, false);
     AddonManagerPrivate.callAddonListeners(aVal ? "onDisabled" : "onEnabled", this);
     return aVal;
   });
 
   this.__defineGetter__("blocklistState", function() {
     let bs = Cc["@mozilla.org/extensions/blocklist;1"].
              getService(Ci.nsIBlocklistService);
@@ -221,33 +243,48 @@ function PluginWrapper(aId, aName, aDesc
           size += getDirectorySize(entry);
       }
       entries.close();
       return size;
     }
 
     let size = 0;
     let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-    aTags.forEach(function(aTag) {
-      file.initWithPath(aTag.fullpath);
+    for (let tag of aTags) {
+      file.initWithPath(tag.fullpath);
       if (file.isDirectory())
         size += getDirectorySize(file);
       else
         size += file.fileSize;
-    });
+    }
     return size;
   });
 
+  this.__defineGetter__("pluginLibraries", function() {
+    let libs = [];
+    for (let tag of aTags)
+      libs.push(tag.filename);
+    return libs;
+  });
+
+  this.__defineGetter__("pluginMimeTypes", function() {
+    let types = [];
+    for (let tag of aTags)
+      for (let type of tag.getMimeTypes({}))
+        types.push(type);
+    return types;
+  });
+
   this.__defineGetter__("installDate", function() {
     let date = 0;
     let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-    aTags.forEach(function(aTag) {
-      file.initWithPath(aTag.fullpath);
+    for (let tag of aTags) {
+      file.initWithPath(tag.fullpath);
       date = Math.max(date, file.lastModifiedTime);
-    });
+    }
     return new Date(date);
   });
 
   this.__defineGetter__("scope", function() {
     let path = aTags[0].fullpath;
     // Plugins inside the application directory are in the application scope
     let dir = Services.dirsvc.get("APlugns", Ci.nsIFile);
     if (path.substring(0, dir.path.length) == dir.path)
@@ -283,16 +320,19 @@ function PluginWrapper(aId, aName, aDesc
       else
         permissions |= AddonManager.PERM_CAN_DISABLE;
     }
     return permissions;
   });
 }
 
 PluginWrapper.prototype = {
+  optionsType: AddonManager.OPTIONS_TYPE_INLINE,
+  optionsURL: "chrome://mozapps/content/extensions/pluginPrefs.xul",
+
   get updateDate() {
     return this.installDate;
   },
 
   get isCompatible() {
     return true;
   },
 
--- a/toolkit/mozapps/extensions/content/extensions.css
+++ b/toolkit/mozapps/extensions/content/extensions.css
@@ -50,16 +50,21 @@ xhtml|link {
 .install-status {
   -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#install-status");
 }
 
 .detail-row {
   -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#detail-row");
 }
 
+.text-list {
+  white-space: pre-line;
+  -moz-user-select: element;
+}
+
 setting, row[unsupported="true"] {
   display: none;
 }
 
 setting[type="bool"] {
   display: -moz-grid-line;
   -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#setting-bool");
 }
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/content/pluginPrefs.xul
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!-- 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/.  -->
+
+<!DOCTYPE window SYSTEM "chrome://mozapps/locale/plugins/plugins.dtd">
+
+<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <setting type="control" title="&plugin.file;">
+    <label class="text-list" id="pluginLibraries"/>
+  </setting>
+  <setting type="control" title="&plugin.mimeTypes;">
+    <label class="text-list" id="pluginMimeTypes"/>
+  </setting>
+</vbox>
--- a/toolkit/mozapps/extensions/jar.mn
+++ b/toolkit/mozapps/extensions/jar.mn
@@ -24,12 +24,13 @@ toolkit.jar:
   content/mozapps/extensions/selectAddons.css                   (content/selectAddons.css)
 * content/mozapps/extensions/update.xul                         (content/update.xul)
   content/mozapps/extensions/update.js                          (content/update.js)
   content/mozapps/extensions/eula.xul                           (content/eula.xul)
   content/mozapps/extensions/eula.js                            (content/eula.js)
   content/mozapps/extensions/newaddon.xul                       (content/newaddon.xul)
   content/mozapps/extensions/newaddon.js                        (content/newaddon.js)
   content/mozapps/extensions/setting.xml                        (content/setting.xml)
+  content/mozapps/extensions/pluginPrefs.xul                    (content/pluginPrefs.xul)
   content/mozapps/xpinstall/xpinstallConfirm.xul                (content/xpinstallConfirm.xul)
   content/mozapps/xpinstall/xpinstallConfirm.js                 (content/xpinstallConfirm.js)
   content/mozapps/xpinstall/xpinstallConfirm.css                (content/xpinstallConfirm.css)
   content/mozapps/xpinstall/xpinstallItem.xml                   (content/xpinstallItem.xml)