Bug 1156566 - Report via telemetry when Adobe EME plugin DLL is unexepectedly missing on startup. r=spohl, r=vladan, a=lizzard
authorChris Pearce <cpearce@mozilla.com>
Fri, 15 May 2015 11:50:52 +1200
changeset 267522 26f16f564a81fe13c53b454a277e2bcb863914c2
parent 267521 4572f6af0d5035462682afce507bffb64628c1fd
child 267523 a2e16743fb0b99cca889aaf4c7e355f4436f8985
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl, vladan, lizzard
bugs1156566
milestone39.0
Bug 1156566 - Report via telemetry when Adobe EME plugin DLL is unexepectedly missing on startup. r=spohl, r=vladan, a=lizzard
toolkit/components/telemetry/Histograms.json
toolkit/mozapps/extensions/internal/GMPProvider.jsm
toolkit/mozapps/extensions/test/xpcshell/test_gmpProvider.js
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -7716,16 +7716,30 @@
     "kind": "count"
   },
   "VIDEO_MSE_UNLOAD_STATE": {
     "expires_in_version": "45",
     "kind": "enumerated",
     "n_values": 5,
     "description": "MSE video state when unloading. ended = 0, paused = 1, stalled = 2, seeking = 3, other = 4"
   },
+  "VIDEO_ADOBE_GMP_DISAPPEARED": {
+    "alert_emails": ["cpearce@mozilla.com"],
+    "expires_in_version": "42",
+    "kind": "flag",
+    "description": "Whether or not the Adobe EME GMP was expected to be resident on disk but mysteriously isn't.",
+    "releaseChannelCollection": "opt-out"
+  },
+  "VIDEO_OPENH264_GMP_DISAPPEARED": {
+    "alert_emails": ["cpearce@mozilla.com", "rjesup@mozilla.com"],
+    "expires_in_version": "42",
+    "kind": "flag",
+    "description": "Whether or not the OpenH264 GMP was expected to be resident on disk but mysteriously isn't.",
+    "releaseChannelCollection": "opt-out"
+  },
   "FX_SANITIZE_TOTAL": {
     "alert_emails": ["firefox-dev@mozilla.org", "gavin@mozilla.com"],
     "expires_in_version": "40",
     "kind": "exponential",
     "high": "30000",
     "n_buckets": 20,
     "extended_statistics_ok": true,
     "description": "Sanitize: Total time it takes to sanitize (ms)"
--- a/toolkit/mozapps/extensions/internal/GMPProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/GMPProvider.jsm
@@ -43,38 +43,42 @@ const GMP_PLUGINS = [
     id:              OPEN_H264_ID,
     name:            "openH264_name",
     description:     "openH264_description2",
     // The following licenseURL is part of an awful hack to include the OpenH264
     // license without having bug 624602 fixed yet, and intentionally ignores
     // localisation.
     licenseURL:      "chrome://mozapps/content/extensions/OpenH264-license.txt",
     homepageURL:     "http://www.openh264.org/",
-    optionsURL:      "chrome://mozapps/content/extensions/gmpPrefs.xul"
+    optionsURL:      "chrome://mozapps/content/extensions/gmpPrefs.xul",
+    missingKey:      "VIDEO_OPENH264_GMP_DISAPPEARED",
   },
   {
     id:              EME_ADOBE_ID,
     name:            "eme-adobe_name",
     description:     "eme-adobe_description",
     // The following learnMoreURL is another hack to be able to support a SUMO page for this
     // feature.
     get learnMoreURL() {
       return Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content";
     },
     licenseURL:      "http://help.adobe.com/en_US/primetime/drm/HTML5_CDM_EULA/index.html",
     homepageURL:     "http://help.adobe.com/en_US/primetime/drm/HTML5_CDM",
     optionsURL:      "chrome://mozapps/content/extensions/gmpPrefs.xul",
-    isEME:           true
+    isEME:           true,
+    missingKey:      "VIDEO_ADOBE_GMP_DISAPPEARED",
   }];
 
 XPCOMUtils.defineLazyGetter(this, "pluginsBundle",
   () => Services.strings.createBundle("chrome://global/locale/plugins.properties"));
 XPCOMUtils.defineLazyGetter(this, "gmpService",
   () => Cc["@mozilla.org/gecko-media-plugin-service;1"].getService(Ci.mozIGeckoMediaPluginService));
 
+XPCOMUtils.defineLazyGetter(this, "telemetryService", () => Services.telemetry);  
+
 let messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
                        .getService(Ci.nsIMessageListenerManager);
 
 let gLogger;
 let gLogAppenderDump = null;
 
 function configureLogging() {
   if (!gLogger) {
@@ -135,16 +139,20 @@ GMPWrapper.prototype = {
       this._gmpPath = OS.Path.join(OS.Constants.Path.profileDir,
                                    this._plugin.id,
                                    GMPPrefs.get(GMPPrefs.KEY_PLUGIN_VERSION,
                                                 null, this._plugin.id));
     }
     return this._gmpPath;
   },
 
+  get missingKey() {
+    return this._plugin.missingKey;
+  },
+
   get id() { return this._plugin.id; },
   get type() { return "plugin"; },
   get isGMPlugin() { return true; },
   get name() { return this._plugin.name; },
   get creator() { return null; },
   get homepageURL() { return this._plugin.homepageURL; },
 
   get description() { return this._plugin.description; },
@@ -507,16 +515,17 @@ let GMPProvider = {
       let isEnabled = wrapper.isActive;
       this._log.trace("startup - enabled=" + isEnabled + ", gmpPath=" +
                       gmpPath);
 
       if (gmpPath && isEnabled) {
         if (!wrapper.validate()) {
           this._log.info("startup - gmp " + plugin.id +
                          " missing lib and/or info files, uninstalling");
+          telemetryService.getHistogramById(wrapper.missingKey).add(true);
           wrapper.uninstallPlugin();
           continue;
         }
         this._log.info("startup - adding gmp directory " + gmpPath);
         try {
           gmpService.addPluginDirectory(gmpPath);
         } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
           this._log.warn("startup - adding gmp directory failed with " +
@@ -625,16 +634,17 @@ let GMPProvider = {
       let plugin = {
         id: aPlugin.id,
         name: pluginsBundle.GetStringFromName(aPlugin.name),
         description: pluginsBundle.GetStringFromName(aPlugin.description),
         homepageURL: aPlugin.homepageURL,
         optionsURL: aPlugin.optionsURL,
         wrapper: null,
         isEME: aPlugin.isEME,
+        missingKey: aPlugin.missingKey,
       };
       plugin.fullDescription = this.generateFullDescription(aPlugin);
       plugin.wrapper = new GMPWrapper(plugin);
       this._plugins.set(plugin.id, plugin);
     }
   },
 
   ensureProperCDMInstallState: function() {
--- a/toolkit/mozapps/extensions/test/xpcshell/test_gmpProvider.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_gmpProvider.js
@@ -17,16 +17,17 @@ let gMockEmeAddons = new Map();
 
 for (let plugin of GMPScope.GMP_PLUGINS) {
   let mockAddon = Object.freeze({
       id: plugin.id,
       isValid: true,
       isInstalled: false,
       nameId: plugin.name,
       descriptionId: plugin.description,
+      missingKey: plugin.missingKey,
   });
   gMockAddons.set(mockAddon.id, mockAddon);
   if (mockAddon.id.indexOf("gmp-eme-") == 0) {
     gMockEmeAddons.set(mockAddon.id, mockAddon);
   }
 }
 
 let gInstalledAddonId = "";
@@ -282,28 +283,45 @@ add_task(function* test_pluginRegistrati
       },
       removeAndDeletePluginDirectory: path => {
         if (!removedPaths.includes(path)) {
           removedPaths.push(path);
         }
       },
     };
 
+    let reportedKeys = [];
+
+    let MockTelemetry = {
+      getHistogramById: key => {
+        return {
+          add: value => {
+            reportedKeys.push(key);
+          }
+        }
+      }
+    };
+
     GMPScope.gmpService = MockGMPService;
+    GMPScope.telemetryService = MockTelemetry;
     gPrefs.setBoolPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_ENABLED, addon.id), true);
 
     // Test that plugin registration fails if the plugin dynamic library and
     // info files are not present.
     gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, addon.id),
                        TEST_VERSION);
     clearPaths();
     yield promiseRestartManager();
     Assert.equal(addedPaths.indexOf(file.path), -1);
     Assert.deepEqual(removedPaths, [file.path]);
 
+    // Test that the GMPProvider tried to report via telemetry that the
+    // addon's lib file is missing.
+    Assert.deepEqual(reportedKeys, [addon.missingKey]);
+
     // Create dummy GMP library/info files, and test that plugin registration
     // succeeds during startup, now that we've added GMP info/lib files.
     createMockPluginFilesIfNeeded(file, addon.id);
 
     gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, addon.id),
                        TEST_VERSION);
     clearPaths();
     yield promiseRestartManager();