gecko-dev/browser/extensions/clicktoplay-rollout/bootstrap.js
Benjamin Smedberg bf41cd14bb Bug 1372237 - Balance the test/control groups for Flash rollout. The test group grows up from 0 as it always has. The control group grows down from 1, and everyone else is "excluded" r=felipe
MozReview-Commit-ID: 6BlevKeLp6G

--HG--
extra : rebase_source : 4f2261efe6b3375c8b07f844a4def29dd02754a1
extra : amend_source : c8b9e7174d9cec02bd29ab976614e05a87843863
2017-06-12 10:59:43 -04:00

147 lines
4.3 KiB
JavaScript

/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/TelemetryEnvironment.jsm");
// The amount of people to be part of the rollout
const TEST_THRESHOLD = {
"beta": 0.5, // 50%
"release": 0.05, // 5%
};
if (AppConstants.RELEASE_OR_BETA) {
// The rollout is controlled by the channel name, which
// is the only way to distinguish between Beta and Release.
// However, non-official release builds (like the ones done by distros
// to ship Firefox on their package managers) do not set a value
// for the release channel, which gets them to the default value
// of.. (drumroll) "default".
// But we can't just always configure the same settings for the
// "default" channel because that's also the name that a locally
// built Firefox gets, and CTP is already directly set there
// through an #ifdef in firefox.js
TEST_THRESHOLD.default = TEST_THRESHOLD.release;
}
const PREF_COHORT_SAMPLE = "plugins.ctprollout.cohortSample";
const PREF_COHORT_NAME = "plugins.ctprollout.cohort";
const PREF_FLASH_STATE = "plugin.state.flash";
function startup() {
defineCohort();
}
function defineCohort() {
let updateChannel = UpdateUtils.getUpdateChannel(false);
if (!(updateChannel in TEST_THRESHOLD)) {
return;
}
let cohort = Preferences.get(PREF_COHORT_NAME);
if (!cohort) {
// The cohort has not been defined yet: this is the first
// time that we're running. Let's see if the user has
// a non-default setting to avoid changing it.
let currentPluginState = Preferences.get(PREF_FLASH_STATE);
switch (currentPluginState) {
case Ci.nsIPluginTag.STATE_CLICKTOPLAY:
cohort = "early-adopter-ctp";
break;
case Ci.nsIPluginTag.STATE_DISABLED:
cohort = "early-adopter-disabled";
break;
default:
// intentionally missing from the list is STATE_ENABLED,
// which will keep cohort undefined.
break;
}
}
switch (cohort) {
case undefined:
case "test":
case "control":
{
// If it's either test/control, the cohort might have changed
// if the desired sampling has been changed.
let testThreshold = TEST_THRESHOLD[updateChannel];
let userSample = getUserSample();
if (userSample < testThreshold) {
cohort = "test";
let defaultPrefs = new Preferences({defaultBranch: true});
defaultPrefs.set(PREF_FLASH_STATE, Ci.nsIPluginTag.STATE_CLICKTOPLAY);
} else if (userSample >= 1.0 - testThreshold) {
cohort = "control";
} else {
cohort = "excluded";
}
setCohort(cohort);
watchForPrefChanges();
break;
}
case "early-adopter-ctp":
case "early-adopter-disabled":
default:
// "user-changed-from-*" will fall into this default case and
// not do anything special.
setCohort(cohort);
break;
}
}
function getUserSample() {
let prefValue = Preferences.get(PREF_COHORT_SAMPLE, undefined);
let value = 0.0;
if (typeof(prefValue) == "string") {
value = parseFloat(prefValue, 10);
return value;
}
value = Math.random();
Preferences.set(PREF_COHORT_SAMPLE, value.toString().substr(0, 8));
return value;
}
function setCohort(cohortName) {
Preferences.set(PREF_COHORT_NAME, cohortName);
TelemetryEnvironment.setExperimentActive("clicktoplay-rollout", cohortName);
try {
if (Ci.nsICrashReporter) {
Services.appinfo.QueryInterface(Ci.nsICrashReporter).annotateCrashReport("CTPCohort", cohortName);
}
} catch (e) {}
}
function watchForPrefChanges() {
Preferences.observe(PREF_FLASH_STATE, function() {
let currentCohort = Preferences.get(PREF_COHORT_NAME, "unknown");
setCohort(`user-changed-from-${currentCohort}`);
});
}
function install() {
}
function shutdown(data, reason) {
}
function uninstall() {
}