Bug 1271483 - p10. Front-end handling of prefs&telemetry - r=gijs
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 26 May 2016 23:46:52 +1000
changeset 302281 60ea602c56cd331055f3b1dbe37d6f47a68a22c7
parent 302280 e7a336a48fa292c95f24d36984b55d2e28dab1b8
child 302282 93bc3bb0c1be31bfa9057782b7af069ac71bedf2
push id78676
push usergsquelart@mozilla.com
push dateWed, 22 Jun 2016 03:54:32 +0000
treeherdermozilla-inbound@da005aa1d83c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgijs
bugs1271483
milestone50.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 1271483 - p10. Front-end handling of prefs&telemetry - r=gijs When an issue is reported, save the unplayable formats/key-systesm in a pref, keyed by the detailed issue string id, and report the infobar-shown telemetry. More telemetry when the "Show me how" button is clicked. And final telemetry (and clearing the prefs) when the issue is solved. MozReview-Commit-ID: 4PgaPMVfjsQ
browser/base/content/browser-media.js
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -190,16 +190,22 @@ var gEMEHandler = {
   },
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener])
 };
 
 XPCOMUtils.defineLazyGetter(gEMEHandler, "_brandShortName", function() {
   return document.getElementById("bundle_brand").getString("brandShortName");
 });
 
+const TELEMETRY_DDSTAT_SHOWN = 0;
+const TELEMETRY_DDSTAT_SHOWN_FIRST = 1;
+const TELEMETRY_DDSTAT_CLICKED = 2;
+const TELEMETRY_DDSTAT_CLICKED_FIRST = 3;
+const TELEMETRY_DDSTAT_SOLVED = 4;
+
 let gDecoderDoctorHandler = {
   shouldShowLearnMoreButton() {
     return AppConstants.platform == "win";
   },
 
   getLabelForNotificationBox(type) {
     if (type == "adobe-cdm-not-found" &&
         AppConstants.platform == "win") {
@@ -236,42 +242,103 @@ let gDecoderDoctorHandler = {
 
     let parsedData;
     try {
       parsedData = JSON.parse(data);
     } catch (ex) {
       Cu.reportError("Malformed Decoder Doctor message with data: " + data);
       return;
     }
-    let {type} = parsedData;
+    // parsedData (the result of parsing the incoming 'data' json string)
+    // contains analysis information from Decoder Doctor:
+    // - 'type' is the type of issue, it determines which text to show in the
+    //   infobar.
+    // - 'decoderDoctorReportId' is the Decoder Doctor issue identifier, to be
+    //   used here as key for the telemetry (counting infobar displays,
+    //   "Learn how" buttons clicks, and resolutions) and for the prefs used
+    //   to store at-issue formats.
+    // - 'formats' contains a comma-separated list of formats (or key systems)
+    //   that suffer the issue. These are kept in a pref, which the backend
+    //   uses to later find when an issue is resolved.
+    // - 'isSolved' is true when the notification actually indicates the
+    //   resolution of that issue, to be reported as telemetry.
+    let {type, isSolved, decoderDoctorReportId, formats} = parsedData;
     type = type.toLowerCase();
     let title = gDecoderDoctorHandler.getLabelForNotificationBox(type);
     if (!title) {
       return;
     }
 
-    let buttons = [];
-    if (gDecoderDoctorHandler.shouldShowLearnMoreButton()) {
-      buttons.push({
-        label: gNavigatorBundle.getString("decoder.noCodecs.button"),
-        accessKey: gNavigatorBundle.getString("decoder.noCodecs.accesskey"),
-        callback() {
-          let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
-          openUILinkIn(baseURL + "fix-video-audio-problems-firefox-windows", "tab");
+    // We keep the list of formats in prefs for the sake of the decoder itself,
+    // which reads it to determine when issues get solved for these formats.
+    // (Writing prefs from e10s content is now allowed.)
+    let formatsPref = "media.decoder-doctor." + decoderDoctorReportId + ".formats";
+    let buttonClickedPref = "media.decoder-doctor." + decoderDoctorReportId + ".button-clicked";
+    let histogram =
+      Services.telemetry.getKeyedHistogramById("DECODER_DOCTOR_INFOBAR_STATS");
+
+    let formatsInPref = Services.prefs.getPrefType(formatsPref) &&
+                        Services.prefs.getCharPref(formatsPref);
+
+    if (!isSolved) {
+      if (!formats) {
+        Cu.reportError("Malformed Decoder Doctor unsolved message with no formats");
+        return;
+      }
+      if (!formatsInPref) {
+        Services.prefs.setCharPref(formatsPref, formats);
+        histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SHOWN_FIRST);
+      } else {
+        // Split existing formats into an array of strings.
+        let existing = formatsInPref.split(",").map(String.trim);
+        // Keep given formats that were not already recorded.
+        let newbies = formats.split(",").map(String.trim)
+                      .filter(x => existing.includes(x));
+        // And rewrite pref with the added new formats (if any).
+        if (newbies.length) {
+          Services.prefs.setCharPref(formatsPref,
+                                     existing.concat(newbies).join(", "));
         }
-      });
-    }
+      }
+      histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SHOWN);
+
+      let buttons = [];
+      if (gDecoderDoctorHandler.shouldShowLearnMoreButton()) {
+        buttons.push({
+          label: gNavigatorBundle.getString("decoder.noCodecs.button"),
+          accessKey: gNavigatorBundle.getString("decoder.noCodecs.accesskey"),
+          callback() {
+            let clickedInPref = Services.prefs.getPrefType(buttonClickedPref) &&
+                                Services.prefs.getBoolPref(buttonClickedPref);
+            if (!clickedInPref) {
+              Services.prefs.setBoolPref(buttonClickedPref, true);
+              histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED_FIRST);
+            }
+            histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_CLICKED);
 
-    box.appendNotification(
-      title,
-      notificationId,
-      "", // This uses the info icon as specified below.
-      box.PRIORITY_INFO_LOW,
-      buttons
-    );
+            let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
+            openUILinkIn(baseURL + "fix-video-audio-problems-firefox-windows", "tab");
+          }
+        });
+      }
+
+      box.appendNotification(
+          title,
+          notificationId,
+          "", // This uses the info icon as specified below.
+          box.PRIORITY_INFO_LOW,
+          buttons
+      );
+    } else if (formatsInPref) {
+      // Issue is solved, and prefs haven't been cleared yet, meaning it's the
+      // first time we get this resolution -> Clear prefs and report telemetry.
+      Services.prefs.clearUserPref(formatsPref);
+      Services.prefs.clearUserPref(buttonClickedPref);
+      histogram.add(decoderDoctorReportId, TELEMETRY_DDSTAT_SOLVED);
+    }
   },
 }
 
 window.messageManager.addMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);
 window.messageManager.addMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
 window.addEventListener("unload", function() {
   window.messageManager.removeMessageListener("EMEVideo:ContentMediaKeysRequest", gEMEHandler);
   window.messageManager.removeMessageListener("DecoderDoctor:Notification", gDecoderDoctorHandler);