Bug 1403695 - Send a generic health telemetry ping through Ping Centre for Activity Stream. r=k88hudson, a=ritu
authorMarina Samuel <msamuel@mozilla.com>
Wed, 27 Sep 2017 16:29:06 -0400
changeset 677875 3d3fb23661100dbd4a2b47d692029fc332fe4fcb
parent 677874 b0fd47b5c0f35d8c22e465316defd7a0c5a33a9c
child 677876 4a1a1eab35ce97053558e791745a02b616983c66
push id83805
push userbmo:rail@mozilla.com
push dateTue, 10 Oct 2017 19:01:30 +0000
reviewersk88hudson, ritu
bugs1403695
milestone57.0
Bug 1403695 - Send a generic health telemetry ping through Ping Centre for Activity Stream. r=k88hudson, a=ritu MozReview-Commit-ID: CJGX1aihFuV
browser/components/nsBrowserGlue.js
browser/components/tests/unit/head.js
browser/components/tests/unit/test_browserGlue_pingcentre.js
browser/components/tests/unit/xpcshell.ini
layout/tools/reftest/reftest-preferences.js
testing/profiles/prefs_general.js
testing/talos/talos/config.py
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -44,16 +44,17 @@ XPCOMUtils.defineLazyModuleGetters(this,
   LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
   NetUtil: "resource://gre/modules/NetUtil.jsm",
   NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   PageActions: "resource:///modules/PageActions.jsm",
   PageThumbs: "resource://gre/modules/PageThumbs.jsm",
   PdfJs: "resource://pdf.js/PdfJs.jsm",
   PermissionUI: "resource:///modules/PermissionUI.jsm",
+  PingCentre: "resource:///modules/PingCentre.jsm",
   PlacesBackups: "resource://gre/modules/PlacesBackups.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   PluralForm: "resource://gre/modules/PluralForm.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   ProcessHangMonitor: "resource:///modules/ProcessHangMonitor.jsm",
   ReaderParent: "resource:///modules/ReaderParent.jsm",
   RecentWindow: "resource:///modules/RecentWindow.jsm",
   RemotePrompt: "resource:///modules/RemotePrompt.jsm",
@@ -292,16 +293,40 @@ BrowserGlue.prototype = {
       delay += browserEnum.getNext().gBrowser.tabs.length;
     }
     delay = delay <= MAX_DELAY ? delay : MAX_DELAY;
 
     Cu.import("resource://services-sync/main.js");
     Weave.Service.scheduler.delayedAutoConnect(delay);
   },
 
+  /**
+   * Lazily initialize PingCentre
+   */
+  get pingCentre() {
+    const MAIN_TOPIC_ID = "main";
+    Object.defineProperty(this, "pingCentre", {
+      value: new PingCentre({ topic: MAIN_TOPIC_ID })
+    });
+    return this.pingCentre;
+  },
+
+  _sendMainPingCentrePing() {
+    const ACTIVITY_STREAM_ENABLED_PREF = "browser.newtabpage.activity-stream.enabled";
+    const ACTIVITY_STREAM_ID = "activity-stream";
+    let asEnabled = Services.prefs.getBoolPref(ACTIVITY_STREAM_ENABLED_PREF, false);
+
+    const payload = {
+      event: "AS_ENABLED",
+      value: asEnabled
+    };
+    const options = {filter: ACTIVITY_STREAM_ID};
+    this.pingCentre.sendPing(payload, options);
+  },
+
   // nsIObserver implementation
   observe: function BG_observe(subject, topic, data) {
     switch (topic) {
       case "notifications-open-settings":
         this._openPreferences("privacy", { origin: "notifOpenSettings" });
         break;
       case "prefservice:after-app-defaults":
         this._onAppDefaults();
@@ -484,16 +509,19 @@ BrowserGlue.prototype = {
         // happens once since PdfJs registers global hooks. If the PdfJs
         // extension is installed the init method below will be overridden
         // leaving initialization to the extension.
         // parent only: configure default prefs, set up pref observers, register
         // pdf content handler, and initializes parent side message manager
         // shim for privileged api access.
         PdfJs.init(true);
         break;
+      case "shield-init-complete":
+        this._sendMainPingCentrePing();
+        break;
     }
   },
 
   // initialization (called on application startup)
   _init: function BG__init() {
     let os = Services.obs;
     os.addObserver(this, "notifications-open-settings");
     os.addObserver(this, "prefservice:after-app-defaults");
@@ -520,16 +548,17 @@ BrowserGlue.prototype = {
     os.addObserver(this, "profile-before-change");
     os.addObserver(this, "keyword-search");
     os.addObserver(this, "browser-search-engine-modified");
     os.addObserver(this, "restart-in-safe-mode");
     os.addObserver(this, "flash-plugin-hang");
     os.addObserver(this, "xpi-signature-changed");
     os.addObserver(this, "sync-ui-state:update");
     os.addObserver(this, "handlersvc-store-initialized");
+    os.addObserver(this, "shield-init-complete");
 
     this._flashHangCount = 0;
     this._firstWindowReady = new Promise(resolve => this._firstWindowLoaded = resolve);
     if (AppConstants.platform == "win") {
       JawsScreenReaderVersionCheck.init();
     }
   },
 
@@ -572,16 +601,17 @@ BrowserGlue.prototype = {
     } catch (ex) { /* Could have been removed already */ }
     os.removeObserver(this, "handle-xul-text-link");
     os.removeObserver(this, "profile-before-change");
     os.removeObserver(this, "keyword-search");
     os.removeObserver(this, "browser-search-engine-modified");
     os.removeObserver(this, "flash-plugin-hang");
     os.removeObserver(this, "xpi-signature-changed");
     os.removeObserver(this, "sync-ui-state:update");
+    os.removeObserver(this, "shield-init-complete");
   },
 
   _onAppDefaults: function BG__onAppDefaults() {
     // apply distribution customizations (prefs)
     // other customizations are applied in _beforeUIStartup()
     this._distributionCustomizer.applyPrefDefaults();
   },
 
@@ -950,16 +980,20 @@ BrowserGlue.prototype = {
 
     for (let mod of Object.values(initializedModules)) {
       if (mod.uninit) {
         mod.uninit();
       }
     }
 
     BrowserUsageTelemetry.uninit();
+    // Only uninit PingCentre if the getter has initialized it
+    if (Object.prototype.hasOwnProperty.call(this, "pingCentre")) {
+      this.pingCentre.uninit();
+    }
 
     PageThumbs.uninit();
     NewTabUtils.uninit();
     AutoCompletePopup.uninit();
     DateTimePickerHelper.uninit();
   },
 
   // All initial windows have opened.
--- a/browser/components/tests/unit/head.js
+++ b/browser/components/tests/unit/head.js
@@ -1,9 +1,18 @@
 /* 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/. */
 
 const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
+// ================================================
+// Load mocking/stubbing library, sinon
+// docs: http://sinonjs.org/releases/v2.3.2/
+/* exported sinon */
+Cu.import("resource://gre/modules/Timer.jsm");
+Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js", this);
+/* globals sinon */
+// ================================================
+
 var gProfD = do_get_profile().QueryInterface(Ci.nsIFile);
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/unit/test_browserGlue_pingcentre.js
@@ -0,0 +1,25 @@
+Cu.import("resource:///modules/PingCentre.jsm");
+
+const TOPIC_SHIELD_INIT_COMPLETE = "shield-init-complete";
+const ACTIVITY_STREAM_ENABLED_PREF = "browser.newtabpage.activity-stream.enabled";
+const SEND_PING_MOCK = sinon.stub(PingCentre.prototype, "sendPing");
+
+let gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"]
+                     .getService(Ci.nsIObserver);
+
+add_task(async function() {
+  let asEnabled = Services.prefs.getBoolPref(ACTIVITY_STREAM_ENABLED_PREF, false);
+
+  // Simulate ping centre sendPing() trigger.
+  gBrowserGlue.observe(null, TOPIC_SHIELD_INIT_COMPLETE, null);
+
+  const SEND_PING_CALL_ARGS = {
+    event: "AS_ENABLED",
+    value: asEnabled
+  }
+  const SEND_PING_FILTER = { filter: "activity-stream" };
+
+  Assert.ok(SEND_PING_MOCK.called, "gBrowserGlue.pingCentre.sendPing() is called");
+  Assert.ok(SEND_PING_MOCK.calledWithExactly(SEND_PING_CALL_ARGS, SEND_PING_FILTER),
+    "sendPing() is called with the correct param");
+});
--- a/browser/components/tests/unit/xpcshell.ini
+++ b/browser/components/tests/unit/xpcshell.ini
@@ -3,8 +3,9 @@ head = head.js
 firefox-appdir = browser
 skip-if = toolkit == 'android'
 support-files =
   distribution.ini
   data/engine-de-DE.xml
 
 [test_distribution.js]
 [test_browserGlue_migration_loop_cleanup.js]
+[test_browserGlue_pingcentre.js]
--- a/layout/tools/reftest/reftest-preferences.js
+++ b/layout/tools/reftest/reftest-preferences.js
@@ -61,16 +61,20 @@ user_pref("layout.interruptible-reflow.e
 // desired side-effect of preventing our geoip lookup.
 user_pref("browser.search.isUS", true);
 user_pref("browser.search.countryCode", "US");
 user_pref("browser.search.geoSpecificDefaults", false);
 
 // Make sure Shield doesn't hit the network.
 user_pref("extensions.shield-recipe-client.api_url", "https://localhost/selfsupport-dummy/");
 
+// Make sure Ping Centre doesn't hit the network.
+user_pref("browser.ping-centre.staging.endpoint", "https://localhost");
+user_pref("browser.ping-centre.production.endpoint", "https://localhost");
+
 // use about:blank, not browser.startup.homepage
 user_pref("browser.startup.page", 0);
 
 // Allow XUL and XBL files to be opened from file:// URIs
 user_pref("dom.allow_XUL_XBL_for_file", true);
 
 // Allow view-source URIs to be opened from URIs that share
 // their protocol with the inner URI of the view-source URI
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -322,16 +322,20 @@ user_pref("browser.uitour.url", "http://
 user_pref("browser.search.isUS", true);
 user_pref("browser.search.countryCode", "US");
 // This will prevent HTTP requests for region defaults.
 user_pref("browser.search.geoSpecificDefaults", false);
 
 // Make sure Shield doesn't hit the network.
 user_pref("extensions.shield-recipe-client.api_url", "");
 
+// Make sure PingCentre doesn't hit the network.
+user_pref("browser.ping-centre.staging.endpoint", "");
+user_pref("browser.ping-centre.production.endpoint", "");
+
 user_pref("media.eme.enabled", true);
 
 // Set the number of shmems the PChromiumCDM protocol pre-allocates to 0,
 // so that we test the case where we under-estimate how many shmems we need
 // to send decoded video frames from the CDM to Gecko.
 user_pref("media.eme.chromium-api.video-shmems", 0);
 
 user_pref("media.autoplay.enabled", true);
--- a/testing/talos/talos/config.py
+++ b/testing/talos/talos/config.py
@@ -156,16 +156,20 @@ DEFAULTS = dict(
             'http://127.0.0.1/extensions-dummy/repositorySearchURL',
         'media.gmp-manager.url':
             'http://127.0.0.1/gmpmanager-dummy/update.xml',
         'media.gmp-manager.updateEnabled': False,
         'extensions.systemAddon.update.url':
             'http://127.0.0.1/dummy-system-addons.xml',
         'extensions.shield-recipe-client.api_url':
             'https://127.0.0.1/selfsupport-dummy/',
+        'browser.ping-centre.staging.endpoint':
+            'https://127.0.0.1/pingcentre/dummy/',
+        'browser.ping-centre.production.endpoint':
+            'https://127.0.0.1/pingcentre/dummy/',
         'media.navigator.enabled': True,
         'media.peerconnection.enabled': True,
         'media.navigator.permission.disabled': True,
         'media.capturestream_hints.enabled': True,
         'browser.contentHandlers.types.0.uri': 'http://127.0.0.1/rss?url=%s',
         'browser.contentHandlers.types.1.uri': 'http://127.0.0.1/rss?url=%s',
         'browser.contentHandlers.types.2.uri': 'http://127.0.0.1/rss?url=%s',
         'browser.contentHandlers.types.3.uri': 'http://127.0.0.1/rss?url=%s',