Bug 1501329 - Expose "wasCanary" flag in saved-session pings for Fennec. r=chutten, a=RyanVM
authorJan-Erik Rediger <jrediger@mozilla.com>
Fri, 26 Oct 2018 20:05:53 +0000
changeset 500953 c7c256c66f93a5c31efdd573aab6e4322fb50ea8
parent 500952 455c4d904d2778da6d3cd86ac960d4f20ac99eb4
child 500954 02cbbb3db3b576d57ad3f6f74916ea6d4b4f3306
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschutten, RyanVM
bugs1501329
milestone64.0
Bug 1501329 - Expose "wasCanary" flag in saved-session pings for Fennec. r=chutten, a=RyanVM Depends on D9903 Depends on D9903 Differential Revision: https://phabricator.services.mozilla.com/D9904
toolkit/components/telemetry/app/TelemetryController.jsm
toolkit/components/telemetry/docs/data/environment.rst
toolkit/components/telemetry/tests/unit/test_TelemetryClientID_reset.js
--- a/toolkit/components/telemetry/app/TelemetryController.jsm
+++ b/toolkit/components/telemetry/app/TelemetryController.jsm
@@ -370,16 +370,21 @@ var Impl = {
     };
 
     if (aOptions.addClientId) {
       pingData.clientId = this._clientID;
     }
 
     if (aOptions.addEnvironment) {
       pingData.environment = aOptions.overrideEnvironment || TelemetryEnvironment.currentEnvironment;
+
+      // On Android store a flag if the client ID was reset from a canary ID.
+      if (AppConstants.platform == "android" && ClientID.wasCanaryClientID()) {
+        pingData.environment.profile.wasCanary = true;
+      }
     }
 
     return pingData;
   },
 
   /**
    * Track any pending ping send and save tasks through the promise passed here.
    * This is needed to block shutdown on any outstanding ping activity.
--- a/toolkit/components/telemetry/docs/data/environment.rst
+++ b/toolkit/components/telemetry/docs/data/environment.rst
@@ -69,16 +69,17 @@ Structure:
         sandbox: {
           effectiveContentProcessLevel: <integer>,
         }
       },
       profile: {
         creationDate: <integer>, // integer days since UNIX epoch, e.g. 16446
         resetDate: <integer>, // integer days since UNIX epoch, e.g. 16446 - optional
         firstUseDate: <integer>, // integer days since UNIX epoch, e.g. 16446 - optional
+        wasCanary: <bool>, // Android only: true if this profile previously had a canary client ID
       },
       partner: { // This section may not be immediately available on startup
         distributionId: <string>, // pref "distribution.id", null on failure
         distributionVersion: <string>, // pref "distribution.version", null on failure
         partnerId: <string>, // pref mozilla.partner.id, null on failure
         distributor: <string>, // pref app.distributor, null on failure
         distributorChannel: <string>, // pref app.distributor.channel, null on failure
         partnerNames: [
@@ -386,16 +387,22 @@ It's read from a file-stored timestamp f
 
 firstUseDate
 ~~~~~~~~~~~~
 
 The time of the first use of profile. If this is an old profile where we can't
 determine this this field will not be present.
 It's read from a file-stored timestamp from the client's profile directory.
 
+wasCanary
+~~~~~~~~~
+
+Android-only. This attribute is set to ``true`` if the client ID was erroneously set to a canary client ID before
+and later reset to a new random client ID. The attribute is not included if the client ID was not changed.
+
 partner
 -------
 
 If the user is using a partner repack, this contains information identifying the repack being used, otherwise "partnerNames" will be an empty array and other entries will be null. The information may be missing when the profile just becomes available. In Firefox for desktop, the information along with other customizations defined in distribution.ini are processed later in the startup phase, and will be fully applied when "distribution-customization-complete" notification is sent.
 
 Distributions are most reliably identified by the ``distributionId`` field. Partner information can be found in the `partner repacks <https://github.com/mozilla-partners>`_ (`the old one <https://hg.mozilla.org/build/partner-repacks/>`_ is deprecated): it contains one private repository per partner.
 Important values for ``distributionId`` include:
 
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryClientID_reset.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryClientID_reset.js
@@ -224,11 +224,52 @@ add_task(async function test_clientid_ca
   await TelemetryController.testShutdown();
   await TelemetryStorage.testClearPendingPings();
   await TelemetryController.testReset();
 
   newClientId = await ClientID.getClientID();
   Assert.equal(firstClientId, newClientId, "Client ID should be unmodified");
 });
 
+/**
+ * On Android Telemetry is not unified.
+ * Test that we record the canary flag after detecting a canary client ID and resetting to a new ID.
+ */
+add_task(async function test_clientid_canary_nonunified_canary_detected() {
+  const isUnified = Preferences.get(TelemetryUtils.Preferences.Unified, false);
+  if (isUnified) {
+    // Skipping the test if unified telemetry is on.
+    return;
+  }
+
+  let firstClientId = await ClientID.resetClientID();
+  await TelemetryController.testReset();
+  await sendPing(/* environment */ true);
+  let ping = await PingServer.promiseNextPing();
+  Assert.equal(ping.type, TEST_PING_TYPE, "The ping must be a test ping");
+  Assert.equal(firstClientId, ping.clientId, "Client ID should be from the reset");
+  Assert.ok(!("wasCanary" in ping.environment.profile));
+
+  // Setting canary
+  await ClientID.setClientID(TelemetryUtils.knownClientID);
+
+  // Reset the controller to reset the client ID.
+  await TelemetryController.testReset();
+  await sendPing(/* environment */ true);
+  ping = await PingServer.promiseNextPing();
+  Assert.equal(ping.type, TEST_PING_TYPE, "The ping must be a test ping");
+  let clientId = ping.clientId;
+  Assert.notEqual(TelemetryUtils.knownClientID, clientId, "Client ID should have been reset to a valid one.");
+  Assert.notEqual(firstClientId, clientId, "Client ID should be a new one after reset.");
+  Assert.ok(ping.environment.profile.wasCanary, "Previous canary client ID should have been detected after reset.");
+
+  // Reset the controller again.
+  await TelemetryController.testReset();
+  await sendPing(/* environment */ true);
+  ping = await PingServer.promiseNextPing();
+  Assert.equal(ping.type, TEST_PING_TYPE, "The ping must be a test ping");
+  Assert.equal(clientId, ping.clientId, "Client ID should be unmodified now.");
+  Assert.ok(ping.environment.profile.wasCanary, "Canary client ID flag should be persisted.");
+});
+
 add_task(async function stopServer() {
   await PingServer.stop();
 });