Bug 1365714 - Part 2 - System add-on to control rollout of the CTP feature. r=bsmedberg draft
authorFelipe Gomes <felipc@gmail.com>
Fri, 09 Jun 2017 14:28:10 -0300
changeset 591915 c921c8c872dd11a4e9face0c0163f4ca8f03fb34
parent 591914 4a65c9b88ae827cfbbc1339d5b68a05b4475b76a
child 632658 f0aa2bafafcd618e107d3d2f2ac2b43927220360
push id63210
push userfelipc@gmail.com
push dateFri, 09 Jun 2017 17:28:48 +0000
reviewersbsmedberg
bugs1365714
milestone55.0a1
Bug 1365714 - Part 2 - System add-on to control rollout of the CTP feature. r=bsmedberg MozReview-Commit-ID: HWdnOA4PoyX
browser/extensions/clicktoplay-rollout/bootstrap.js
browser/extensions/clicktoplay-rollout/install.rdf.in
browser/extensions/clicktoplay-rollout/moz.build
browser/extensions/moz.build
testing/talos/talos/xtalos/xperf_whitelist.json
new file mode 100644
--- /dev/null
+++ b/browser/extensions/clicktoplay-rollout/bootstrap.js
@@ -0,0 +1,144 @@
+/* -*- 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 = Prefs.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 = Prefs.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 testGroup = (getUserSample(false) < testThreshold);
+
+      if (testGroup) {
+        cohort = "test";
+        let defaultPrefs = new Preferences({defaultBranch: true});
+        defaultPrefs.set(PREF_FLASH_STATE, Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+      } else {
+        cohort = "control";
+      }
+
+      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);
+      return;
+  }
+}
+
+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, 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() {
+}
copy from browser/extensions/e10srollout/install.rdf.in
copy to browser/extensions/clicktoplay-rollout/install.rdf.in
--- a/browser/extensions/e10srollout/install.rdf.in
+++ b/browser/extensions/clicktoplay-rollout/install.rdf.in
@@ -4,29 +4,29 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 #filter substitution
 
 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
 
   <Description about="urn:mozilla:install-manifest">
-    <em:id>e10srollout@mozilla.org</em:id>
-    <em:version>1.50</em:version>
+    <em:id>clicktoplay-rollout@mozilla.org</em:id>
+    <em:version>1.0</em:version>
     <em:type>2</em:type>
     <em:bootstrap>true</em:bootstrap>
     <em:multiprocessCompatible>true</em:multiprocessCompatible>
 
     <!-- Target Application this theme can install into,
         with minimum and maximum supported versions. -->
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
         <em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
       </Description>
     </em:targetApplication>
 
     <!-- Front End MetaData -->
-    <em:name>Multi-process staged rollout</em:name>
-    <em:description>Staged rollout of Firefox multi-process feature.</em:description>
+    <em:name>Click-to-Play staged rollout</em:name>
+    <em:description>Staged rollout for Click-to-Play Flash.</em:description>
   </Description>
 </RDF>
copy from browser/extensions/e10srollout/moz.build
copy to browser/extensions/clicktoplay-rollout/moz.build
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -1,16 +1,17 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += [
     'aushelper',
+    'clicktoplay-rollout',
     'e10srollout',
     'pdfjs',
     'pocket',
     'screenshots',
     'webcompat',
 ]
 
 # Only include the following system add-ons if building Aurora or Nightly
--- a/testing/talos/talos/xtalos/xperf_whitelist.json
+++ b/testing/talos/talos/xtalos/xperf_whitelist.json
@@ -2,16 +2,17 @@
  "C:\\$Mft": {"ignore": true},
  "C:\\$Extend\\$UsnJrnl:$J": {"ignore": true},
  "C:\\Windows\\Prefetch\\{prefetch}.pf": {"ignore": true},
  "C:\\$Secure": {"ignore": true},
  "C:\\$logfile": {"ignore": true},
  "{firefox}\\omni.ja": {"mincount": 0, "maxcount": 46, "minbytes": 0, "maxbytes": 3014656},
  "{firefox}\\browser\\omni.ja": {"mincount": 0, "maxcount": 28, "minbytes": 0, "maxbytes": 1835008},
  "{firefox}\\browser\\features\\aushelper@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
+ "{firefox}\\browser\\features\\clicktoplay-rollout@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\e10srollout@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\flyweb@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\formautofill@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\loop@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\firefox@getpocket.com.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\presentation@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\webcompat@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
  "{firefox}\\browser\\features\\webcompat-reporter@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},