Bug 1101487 - Cache client id in prefs so we can submit it for very short sessions too. r=vladan
--- a/toolkit/components/telemetry/TelemetryPing.jsm
+++ b/toolkit/components/telemetry/TelemetryPing.jsm
@@ -15,28 +15,30 @@ Cu.import("resource://gre/modules/Servic
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/Task.jsm", this);
Cu.import("resource://gre/modules/AsyncShutdown.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)
#expand const HISTOGRAMS_FILE_VERSION = "__HISTOGRAMS_FILE_VERSION__";
const PREF_BRANCH = "toolkit.telemetry.";
const PREF_SERVER = PREF_BRANCH + "server";
const PREF_ENABLED = PREF_BRANCH + "enabled";
const PREF_PREVIOUS_BUILDID = PREF_BRANCH + "previousBuildID";
+const PREF_CACHED_CLIENTID = PREF_BRANCH + "cachedClientID"
const PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
// Do not gather data more than once a minute
const TELEMETRY_INTERVAL = 60000;
// Delay before intializing telemetry (ms)
const TELEMETRY_DELAY = 60000;
// Delay before initializing telemetry if we're testing (ms)
const TELEMETRY_TEST_DELAY = 100;
@@ -950,16 +952,22 @@ let Impl = {
}
if (!enabled) {
// Turn off local telemetry if telemetry is disabled.
// This may change once about:telemetry is added.
Telemetry.canRecord = false;
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);
+
AsyncShutdown.sendTelemetry.addBlocker(
"Telemetry: shutting down",
function condition(){
this.uninstall();
if (Telemetry.canSend) {
return this.savePendingPings();
}
}.bind(this));
@@ -993,16 +1001,21 @@ let Impl = {
yield this.send("overdue-flush", this._server);
}
if ("@mozilla.org/datareporting/service;1" in Cc) {
let drs = Cc["@mozilla.org/datareporting/service;1"]
.getService(Ci.nsISupports)
.wrappedJSObject;
this._clientID = yield drs.getClientID();
+ // Update cached client id.
+ Preferences.set(PREF_CACHED_CLIENTID, this._clientID);
+ } else {
+ // Nuke potentially cached client id.
+ Preferences.reset(PREF_CACHED_CLIENTID);
}
this.attachObservers();
this.gatherMemory();
Telemetry.asyncFetchTelemetryData(function () {});
delete this._timer;
deferred.resolve();
@@ -1053,16 +1066,17 @@ let Impl = {
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.
// We only gather startup info once.
if (Object.keys(this._slowSQLStartup).length == 0) {
this.gatherStartupHistograms();
this._slowSQLStartup = Telemetry.slowSQL;
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
@@ -16,16 +16,17 @@ const Cr = Components.results;
Cu.import("resource://testing-common/httpd.js", this);
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/LightweightThemeManager.jsm", this);
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
Cu.import("resource://gre/modules/TelemetryFile.jsm", this);
Cu.import("resource://gre/modules/Task.jsm", this);
Cu.import("resource://gre/modules/Promise.jsm", this);
+Cu.import("resource://gre/modules/Preferences.jsm");
const IGNORE_HISTOGRAM = "test::ignore_me";
const IGNORE_HISTOGRAM_TO_CLONE = "MEMORY_HEAP_ALLOCATED";
const IGNORE_CLONED_HISTOGRAM = "test::ignore_me_also";
const ADDON_NAME = "Telemetry test addon";
const ADDON_HISTOGRAM = "addon-histogram";
// Add some unicode characters here to ensure that sending them works correctly.
const FLASH_VERSION = "\u201c1.1.1.1\u201d";
@@ -491,16 +492,22 @@ function actualTest() {
run_next_test();
}
add_task(function* asyncSetup() {
yield TelemetryPing.setup();
if ("@mozilla.org/datareporting/service;1" in Cc) {
gDataReportingClientID = yield gDatareportingService.getClientID();
+
+ // We should have cached the client id now. Lets confirm that by
+ // checking the client id before the async ping setup is finished.
+ let promisePingSetup = TelemetryPing.reset();
+ do_check_eq(TelemetryPing.clientID, gDataReportingClientID);
+ yield promisePingSetup;
}
});
// Ensure that not overwriting an existing file fails silently
add_task(function* test_overwritePing() {
let ping = {slug: "foo"}
yield TelemetryFile.savePing(ping, true);
yield TelemetryFile.savePing(ping, false);