Bug 1103101 - Start Telemetry on content process startup; r=vladan
authorJim Chen <nchen@mozilla.com>
Tue, 06 Jan 2015 16:48:03 -0500
changeset 248119 ffb52826fcfa255157571356b510a74a2a53b570
parent 248118 f2c3615385149c731ee8e20ad1cbc50bbca51db4
child 248120 d8e1bdfff9f50daa585ead2391683eb9e839c8ab
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladan
bugs1103101
milestone37.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 1103101 - Start Telemetry on content process startup; r=vladan
toolkit/components/telemetry/TelemetryPing.jsm
toolkit/components/telemetry/TelemetryStartup.js
toolkit/components/telemetry/TelemetryStartup.manifest
--- a/toolkit/components/telemetry/TelemetryPing.jsm
+++ b/toolkit/components/telemetry/TelemetryPing.jsm
@@ -8,22 +8,17 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/debug.js", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
-#ifndef MOZ_WIDGET_GONK
-Cu.import("resource://gre/modules/LightweightThemeManager.jsm", this);
-#endif
-Cu.import("resource://gre/modules/ThirdPartyCookieProbe.jsm", this);
 Cu.import("resource://gre/modules/Promise.jsm", this);
-Cu.import("resource://gre/modules/AsyncShutdown.jsm", this);
 Cu.import("resource://gre/modules/DeferredTask.jsm", this);
 Cu.import("resource://gre/modules/Preferences.jsm");
 
 // When modifying the payload in incompatible ways, please bump this version number
 const PAYLOAD_VERSION = 1;
 
 // This is the HG changeset of the Histogram.json file, used to associate
 // submitted ping data with its histogram definition (bug 832007)
@@ -59,26 +54,35 @@ function getLocale() {
 }
 
 XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
                                    "@mozilla.org/base/telemetry;1",
                                    "nsITelemetry");
 XPCOMUtils.defineLazyServiceGetter(this, "idleService",
                                    "@mozilla.org/widget/idleservice;1",
                                    "nsIIdleService");
-XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
-                                  "resource://gre/modules/UpdateChannel.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
                                   "resource://gre/modules/AddonManager.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
+                                  "resource://gre/modules/AsyncShutdown.jsm");
+#ifndef MOZ_WIDGET_GONK
+XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
+                                  "resource://gre/modules/LightweightThemeManager.jsm");
+#endif
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryFile",
                                   "resource://gre/modules/TelemetryFile.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "TelemetryLog",
+                                  "resource://gre/modules/TelemetryLog.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ThirdPartyCookieProbe",
+                                  "resource://gre/modules/ThirdPartyCookieProbe.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "UITelemetry",
                                   "resource://gre/modules/UITelemetry.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "TelemetryLog",
-                                  "resource://gre/modules/TelemetryLog.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
+                                  "resource://gre/modules/UpdateChannel.jsm");
 
 function generateUUID() {
   let str = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
   // strip {}
   return str.substring(1, str.length - 1);
 }
 
 /**
@@ -196,17 +200,17 @@ this.TelemetryPing = Object.freeze({
   reset: function() {
     this.uninstall();
     return this.setup();
   },
   /**
    * Used only for testing purposes.
    */
   setup: function() {
-    return Impl.setup(true);
+    return Impl.setupChromeProcess(true);
   },
   /**
    * Used only for testing purposes.
    */
   uninstall: function() {
     try {
       Impl.uninstall();
     } catch (ex) {
@@ -899,50 +903,62 @@ let Impl = {
     Services.obs.removeObserver(this, "cycle-collector-begin");
     if (this._isIdleObserver) {
       idleService.removeIdleObserver(this, IDLE_TIMEOUT_SECONDS);
       this._isIdleObserver = false;
     }
   },
 
   /**
+   * Perform telemetry initialization for either chrome or content process.
+   */
+  enableTelemetryRecording: function enableTelemetryRecording(testing) {
+
+#ifdef MOZILLA_OFFICIAL
+    if (!Telemetry.canSend && !testing) {
+      // We can't send data; no point in initializing observers etc.
+      // Only do this for official builds so that e.g. developer builds
+      // still enable Telemetry based on prefs.
+      Telemetry.canRecord = false;
+      return false;
+    }
+#endif
+
+    let enabled = Preferences.get(PREF_ENABLED, false);
+    this._server = Preferences.get(PREF_SERVER, undefined);
+    if (!enabled) {
+      // Turn off local telemetry if telemetry is disabled.
+      // This may change once about:telemetry is added.
+      Telemetry.canRecord = false;
+      return false;
+    }
+
+    return true;
+  },
+
+  /**
    * Initializes telemetry within a timer. If there is no PREF_SERVER set, don't turn on telemetry.
    */
-  setup: function setup(aTesting) {
+  setupChromeProcess: function setupChromeProcess(testing) {
     // Initialize some probes that are kept in their own modules
     this._thirdPartyCookies = new ThirdPartyCookieProbe();
     this._thirdPartyCookies.init();
 
     // Record old value and update build ID preference if this is the first
     // run with a new build ID.
     let previousBuildID = Preferences.get(PREF_PREVIOUS_BUILDID, undefined);
     let thisBuildID = Services.appinfo.appBuildID;
     // If there is no previousBuildID preference, this._previousBuildID remains
     // undefined so no value is sent in the telemetry metadata.
     if (previousBuildID != thisBuildID) {
       this._previousBuildID = previousBuildID;
       Preferences.set(PREF_PREVIOUS_BUILDID, thisBuildID);
     }
 
-#ifdef MOZILLA_OFFICIAL
-    if (!Telemetry.canSend && !aTesting) {
-      // We can't send data; no point in initializing observers etc.
-      // Only do this for official builds so that e.g. developer builds
-      // still enable Telemetry based on prefs.
-      Telemetry.canRecord = false;
-      return;
-    }
-#endif
-
-    let enabled = Preferences.get(PREF_ENABLED, false);
-    this._server = Preferences.get(PREF_SERVER, undefined);
-    if (!enabled) {
-      // Turn off local telemetry if telemetry is disabled.
-      // This may change once about:telemetry is added.
-      Telemetry.canRecord = false;
+    if (!this.enableTelemetryRecording(testing)) {
       return;
     }
 
     // For very short session durations, we may never load the client
     // id from disk.
     // We try to cache it in prefs to avoid this, even though this may
     // lead to some stale client ids.
     this._clientID = Preferences.get(PREF_CACHED_CLIENTID, null);
@@ -952,17 +968,16 @@ let Impl = {
       function condition(){
         this.uninstall();
         if (Telemetry.canSend) {
           return this.savePendingPings();
         }
       }.bind(this));
 
     Services.obs.addObserver(this, "sessionstore-windows-restored", false);
-    Services.obs.addObserver(this, "quit-application-granted", false);
 #ifdef MOZ_WIDGET_ANDROID
     Services.obs.addObserver(this, "application-background", false);
 #endif
     Services.obs.addObserver(this, "xul-window-visible", false);
     this._hasWindowRestoredObserver = true;
     this._hasXulWindowVisibleObserver = true;
 
     // Delay full telemetry initialization to give the browser time to
@@ -995,22 +1010,44 @@ let Impl = {
       }
 
       this.attachObservers();
       this.gatherMemory();
 
       Telemetry.asyncFetchTelemetryData(function () {});
       deferred.resolve();
 
-    }.bind(this), aTesting ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY);
+    }.bind(this), testing ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY);
 
     delayedTask.arm();
     return deferred.promise;
   },
 
+  /**
+   * Initializes telemetry for a content process.
+   */
+  setupContentProcess: function setupContentProcess() {
+    if (!this.enableTelemetryRecording()) {
+      return;
+    }
+
+    Services.obs.addObserver(this, "content-child-shutdown", false);
+
+    this.gatherStartupHistograms();
+
+    let delayedTask = new DeferredTask(function* () {
+      this._initialized = true;
+
+      this.attachObservers();
+      this.gatherMemory();
+    }.bind(this), TELEMETRY_DELAY);
+
+    delayedTask.arm();
+  },
+
   testLoadHistograms: function testLoadHistograms(file) {
     return TelemetryFile.testLoadHistograms(file);
   },
 
   getFlashVersion: function getFlashVersion() {
     let host = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
     let tags = host.getPluginTags();
 
@@ -1040,17 +1077,16 @@ let Impl = {
     if (this._hasWindowRestoredObserver) {
       Services.obs.removeObserver(this, "sessionstore-windows-restored");
       this._hasWindowRestoredObserver = false;
     }
     if (this._hasXulWindowVisibleObserver) {
       Services.obs.removeObserver(this, "xul-window-visible");
       this._hasXulWindowVisibleObserver = false;
     }
-    Services.obs.removeObserver(this, "quit-application-granted");
 #ifdef MOZ_WIDGET_ANDROID
     Services.obs.removeObserver(this, "application-background", false);
 #endif
     this._clientID = null;
   },
 
   getPayload: function getPayload() {
     // This function returns the current Telemetry payload to the caller.
@@ -1094,17 +1130,21 @@ let Impl = {
   },
 
   /**
    * This observer drives telemetry.
    */
   observe: function (aSubject, aTopic, aData) {
     switch (aTopic) {
     case "profile-after-change":
-      return this.setup();
+      // profile-after-change is only registered for chrome processes.
+      return this.setupChromeProcess();
+    case "app-startup":
+      // app-startup is only registered for content processes.
+      return this.setupContentProcess();
     case "cycle-collector-begin":
       let now = new Date();
       if (!gLastMemoryPoll
           || (TELEMETRY_INTERVAL <= now - gLastMemoryPoll)) {
         gLastMemoryPoll = now;
         this.gatherMemory();
       }
       break;
--- a/toolkit/components/telemetry/TelemetryStartup.js
+++ b/toolkit/components/telemetry/TelemetryStartup.js
@@ -3,26 +3,26 @@
  * 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/. */
 
 "use strict";
 
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
-Cu.import("resource://gre/modules/XPCOMUtils.jsm", this)
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
 /**
  * TelemetryStartup is needed to forward the "profile-after-change" notification
  * to TelemetryPing.jsm.
  */
 function TelemetryStartup() {
 }
 
 TelemetryStartup.prototype.classID = Components.ID("{117b219f-92fe-4bd2-a21b-95a342a9d474}");
 TelemetryStartup.prototype.QueryInterface = XPCOMUtils.generateQI([Components.interfaces.nsIObserver])
-TelemetryStartup.prototype.observe = function(aSubject, aTopic, aData){
-  if (aTopic == "profile-after-change") {
-    TelemetryPing.observe(null, "profile-after-change", null);
+TelemetryStartup.prototype.observe = function(aSubject, aTopic, aData) {
+  if (aTopic == "profile-after-change" || aTopic == "app-startup") {
+    TelemetryPing.observe(null, aTopic, null);
   }
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelemetryStartup]);
--- a/toolkit/components/telemetry/TelemetryStartup.manifest
+++ b/toolkit/components/telemetry/TelemetryStartup.manifest
@@ -1,3 +1,4 @@
 component {117b219f-92fe-4bd2-a21b-95a342a9d474} TelemetryStartup.js
 contract @mozilla.org/base/telemetry-startup;1 {117b219f-92fe-4bd2-a21b-95a342a9d474}
-category profile-after-change TelemetryStartup @mozilla.org/base/telemetry-startup;1
+category profile-after-change TelemetryStartup @mozilla.org/base/telemetry-startup;1 process=main
+category app-startup TelemetryStartup @mozilla.org/base/telemetry-startup;1 process=content