diff --git a/services/datareporting/DataReportingService.js b/services/datareporting/DataReportingService.js index 8f41632114d..25b3abfee14 100644 --- a/services/datareporting/DataReportingService.js +++ b/services/datareporting/DataReportingService.js @@ -391,6 +391,15 @@ DataReportingService.prototype = Object.freeze({ return this._clientID; }), + /** + * Returns the SessionRecorder instance associated with the data reporting service. + * Returns an actual object only if FHR is enabled and after initialization, + * else returns undefined. + */ + getSessionRecorder: function() { + return this.sessionRecorder; + }, + /* * Simulate a restart of the service. This is for testing only. */ diff --git a/toolkit/components/telemetry/TelemetryPing.jsm b/toolkit/components/telemetry/TelemetryPing.jsm index 0c3603c28cf..8ff9ed2d7b7 100644 --- a/toolkit/components/telemetry/TelemetryPing.jsm +++ b/toolkit/components/telemetry/TelemetryPing.jsm @@ -372,6 +372,18 @@ let Impl = { ret.savedPings = TelemetryFile.pingsLoaded; } + ret.activeTicks = -1; + if ("@mozilla.org/datareporting/service;1" in Cc) { + let drs = Cc["@mozilla.org/datareporting/service;1"] + .getService(Ci.nsISupports) + .wrappedJSObject; + + let sr = drs.getSessionRecorder(); + if (sr) { + ret.activeTicks = sr.activeTicks; + } + } + ret.pingsOverdue = TelemetryFile.pingsOverdue; ret.pingsDiscarded = TelemetryFile.pingsDiscarded; diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js index f23cd42c3e8..4a831dbe5a2 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js @@ -45,6 +45,9 @@ let gNumberOfThreadsLaunched = 0; const PREF_BRANCH = "toolkit.telemetry."; const PREF_ENABLED = PREF_BRANCH + "enabled"; const PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled"; +const PREF_FHR_SERVICE_ENABLED = "datareporting.healthreport.service.enabled"; + +const HAS_DATAREPORTINGSERVICE = "@mozilla.org/datareporting/service;1" in Cc; const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); @@ -52,6 +55,7 @@ let gHttpServer = new HttpServer(); let gServerStarted = false; let gRequestIterator = null; let gDataReportingClientID = null; +let gOrigFhrServiceEnabled = true; XPCOMUtils.defineLazyGetter(this, "gDatareportingService", () => Cc["@mozilla.org/datareporting/service;1"] @@ -220,6 +224,9 @@ function checkPayload(request, reason, successfulPings) { do_check_true("maximalNumberOfConcurrentThreads" in payload.simpleMeasurements); do_check_true(payload.simpleMeasurements.maximalNumberOfConcurrentThreads >= gNumberOfThreadsLaunched); + let activeTicks = payload.simpleMeasurements.activeTicks; + do_check_true(HAS_DATAREPORTINGSERVICE ? activeTicks >= 0 : activeTicks == -1); + do_check_eq(payload.simpleMeasurements.failedProfileLockCount, FAILED_PROFILE_LOCK_ATTEMPTS); let profileDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile); @@ -432,6 +439,13 @@ function run_test() { // If we can't test gfxInfo, that's fine, we'll note it later. } + // make sure getSessionRecorder() can be called before the DRS init. + // It's not a requirement that it returns undefined, but that's how it behaves + // now - so just let this test fail if this behavior changes. + if (HAS_DATAREPORTINGSERVICE) { + do_check_true(gDatareportingService.getSessionRecorder() === undefined); + } + // Addon manager needs a profile directory do_get_profile(); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); @@ -441,7 +455,11 @@ function run_test() { // Send the needed startup notifications to the datareporting service // to ensure that it has been initialized. - if ("@mozilla.org/datareporting/service;1" in Cc) { + if (HAS_DATAREPORTINGSERVICE) { + // Initially disable FHR to verify that activeTicks ends up as -1 + gOrigFhrServiceEnabled = Services.prefs.getBoolPref(PREF_FHR_SERVICE_ENABLED, true); + Services.prefs.setBoolPref(PREF_FHR_SERVICE_ENABLED, false); + gDatareportingService.observe(null, "app-startup", null); gDatareportingService.observe(null, "profile-after-change", null); } @@ -495,7 +513,18 @@ function actualTest() { add_task(function* asyncSetup() { yield TelemetryPing.setup(); - if ("@mozilla.org/datareporting/service;1" in Cc) { + // When FHR is disabled or no DRS, the payload's activeTicks should be -1. + do_check_true(TelemetryPing.getPayload().simpleMeasurements.activeTicks == -1); + + if (HAS_DATAREPORTINGSERVICE) { + // after we got the no-FHR activeTicks, re-enable FHR and re-init the DRS. + // Note: this relies on the fact that the data reporting service reinitializes + // itself when calling its 'observe' method, without checking if it's already + // initialized. If this DRS behavior changes, this test would need to be adapted. + Services.prefs.setBoolPref(PREF_FHR_SERVICE_ENABLED, gOrigFhrServiceEnabled); + gDatareportingService.observe(null, "app-startup", null); + gDatareportingService.observe(null, "profile-after-change", null); + gDataReportingClientID = yield gDatareportingService.getClientID(); // We should have cached the client id now. Lets confirm that by