mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1501329 - Persist information about canary after resetting client ID r=chutten
We erroneously reset client IDs on Fennec to a canary client ID. This is now detected and a new valid and random client ID is set. This adds a new boolean attribute "wasCanary" to the `state.json` file generated by ClientID.jsm. Depends on D9544 Differential Revision: https://phabricator.services.mozilla.com/D9903 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
b604174729
commit
b463e79733
@ -15,10 +15,10 @@ const PING_FORMAT_VERSION = 4;
|
||||
const OPTOUT_PING_TYPE = "optout";
|
||||
const TEST_PING_TYPE = "test-ping-type";
|
||||
|
||||
function sendPing() {
|
||||
function sendPing(addEnvironment = false) {
|
||||
let options = {
|
||||
addClientId: true,
|
||||
addEnvironment: false,
|
||||
addEnvironment,
|
||||
};
|
||||
return TelemetryController.submitExternalPing(TEST_PING_TYPE, {}, options);
|
||||
}
|
||||
@ -211,6 +211,7 @@ add_task(async function test_clientid_canary_nonunified_no_pref_trigger() {
|
||||
|
||||
// Restart the instance
|
||||
await TelemetryController.testShutdown();
|
||||
await TelemetryStorage.testClearPendingPings();
|
||||
await TelemetryController.testReset();
|
||||
|
||||
let newClientId = await ClientID.getClientID();
|
||||
@ -221,6 +222,7 @@ add_task(async function test_clientid_canary_nonunified_no_pref_trigger() {
|
||||
|
||||
// Restart the instance
|
||||
await TelemetryController.testShutdown();
|
||||
await TelemetryStorage.testClearPendingPings();
|
||||
await TelemetryController.testReset();
|
||||
|
||||
newClientId = await ClientID.getClientID();
|
||||
|
@ -9,9 +9,12 @@ var EXPORTED_SYMBOLS = ["ClientID"];
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/Log.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
|
||||
const LOGGER_NAME = "Toolkit.Telemetry";
|
||||
const LOGGER_PREFIX = "ClientID::";
|
||||
// Must match ID in TelemetryUtils
|
||||
const CANARY_CLIENT_ID = "c0ffeec0-ffee-c0ff-eec0-ffeec0ffeec0";
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "CommonUtils",
|
||||
"resource://services-common/utils.js");
|
||||
@ -56,6 +59,18 @@ var ClientID = Object.freeze({
|
||||
return ClientIDImpl.getClientID();
|
||||
},
|
||||
|
||||
/**
|
||||
* This returns true if the client ID prior to the last client ID reset was a canary client ID.
|
||||
* Android only. Always returns null on Desktop.
|
||||
*/
|
||||
wasCanaryClientID() {
|
||||
if (AppConstants.platform == "android") {
|
||||
return ClientIDImpl.wasCanaryClientID();
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the client id synchronously without hitting the disk.
|
||||
* This returns:
|
||||
@ -107,6 +122,7 @@ var ClientIDImpl = {
|
||||
_saveClientIdTask: null,
|
||||
_removeClientIdTask: null,
|
||||
_logger: null,
|
||||
_wasCanary: null,
|
||||
|
||||
_loadClientID() {
|
||||
if (this._loadClientIdTask) {
|
||||
@ -130,6 +146,9 @@ var ClientIDImpl = {
|
||||
// Try to load the client id from the DRS state file.
|
||||
try {
|
||||
let state = await CommonUtils.readJSON(gStateFilePath);
|
||||
if (AppConstants.platform == "android" && state && "wasCanary" in state) {
|
||||
this._wasCanary = state.wasCanary;
|
||||
}
|
||||
if (state && this.updateClientID(state.clientID)) {
|
||||
return this._clientID;
|
||||
}
|
||||
@ -157,6 +176,10 @@ var ClientIDImpl = {
|
||||
*/
|
||||
async _saveClientID() {
|
||||
let obj = { clientID: this._clientID };
|
||||
// We detected a canary client ID when resetting, storing this as a flag
|
||||
if (AppConstants.platform == "android" && this._wasCanary) {
|
||||
obj.wasCanary = true;
|
||||
}
|
||||
await OS.File.makeDir(gDatareportingPath);
|
||||
await CommonUtils.writeJSON(obj, gStateFilePath);
|
||||
this._saveClientIdTask = null;
|
||||
@ -176,6 +199,14 @@ var ClientIDImpl = {
|
||||
return Promise.resolve(this._clientID);
|
||||
},
|
||||
|
||||
/**
|
||||
* This returns true if the client ID prior to the last client ID reset was a canary client ID.
|
||||
* Android only. Always returns null on Desktop.
|
||||
*/
|
||||
wasCanaryClientID() {
|
||||
return this._wasCanary;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the client id synchronously without hitting the disk.
|
||||
* This returns:
|
||||
@ -243,6 +274,8 @@ var ClientIDImpl = {
|
||||
},
|
||||
|
||||
async resetClientID() {
|
||||
let oldClientId = this._clientID;
|
||||
|
||||
// Wait for the removal.
|
||||
// Asynchronous calls to getClientID will also be blocked on this.
|
||||
this._removeClientIdTask = this._doRemoveClientID();
|
||||
@ -251,6 +284,11 @@ var ClientIDImpl = {
|
||||
|
||||
await this._removeClientIdTask;
|
||||
|
||||
// On Android we detect resets after a canary client ID.
|
||||
if (AppConstants.platform == "android" ) {
|
||||
this._wasCanary = oldClientId == CANARY_CLIENT_ID;
|
||||
}
|
||||
|
||||
// Generate a new id.
|
||||
return this.getClientID();
|
||||
},
|
||||
|
@ -7,6 +7,7 @@ ChromeUtils.import("resource://gre/modules/ClientID.jsm");
|
||||
ChromeUtils.import("resource://services-common/utils.js");
|
||||
ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
|
||||
const PREF_CACHED_CLIENTID = "toolkit.telemetry.cachedClientID";
|
||||
|
||||
@ -130,3 +131,27 @@ add_task(async function test_resetParallelGet() {
|
||||
Assert.notEqual(firstClientID, newClientID, "After reset client ID should be different.");
|
||||
Assert.equal(newClientID, otherClientID, "Getting the client ID in parallel to a reset should give the same id.");
|
||||
});
|
||||
|
||||
add_task({
|
||||
skip_if: () => AppConstants.platform != "android",
|
||||
}, async function test_FennecCanaryDetect() {
|
||||
const KNOWN_UUID = "c0ffeec0-ffee-c0ff-eec0-ffeec0ffeec0";
|
||||
|
||||
// We should get a valid UUID after reset
|
||||
let firstClientID = await ClientID.resetClientID();
|
||||
Assert.notEqual(KNOWN_UUID, firstClientID, "Client ID should be random.");
|
||||
|
||||
// Set the canary client ID.
|
||||
await ClientID.setClientID(KNOWN_UUID);
|
||||
Assert.equal(KNOWN_UUID, await ClientID.getClientID(), "Client ID should be known canary.");
|
||||
|
||||
let newClientID = await ClientID.resetClientID();
|
||||
Assert.notEqual(KNOWN_UUID, newClientID, "After reset Client ID should be random.");
|
||||
Assert.notEqual(firstClientID, newClientID, "After reset Client ID should be new.");
|
||||
Assert.ok(ClientID.wasCanaryClientID(), "After reset we should have detected a canary client ID");
|
||||
|
||||
let clientID = await ClientID.resetClientID();
|
||||
Assert.notEqual(KNOWN_UUID, clientID, "After reset Client ID should be random.");
|
||||
Assert.notEqual(newClientID, clientID, "After reset Client ID should be new.");
|
||||
Assert.ok(!ClientID.wasCanaryClientID(), "After reset we should not have detected a canary client ID");
|
||||
});
|
||||
|
@ -12,7 +12,6 @@ support-files =
|
||||
skip-if = toolkit == 'android'
|
||||
[test_CanonicalJSON.js]
|
||||
[test_client_id.js]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_Color.js]
|
||||
[test_CreditCard.js]
|
||||
[test_DeferredTask.js]
|
||||
|
Loading…
Reference in New Issue
Block a user