Bug 1336501 - Sync shield-recipe-client from GitHub (ad0f45e) r=Gijs
authorMythmon <mcooper@mozilla.com>
Wed, 08 Feb 2017 09:51:55 -0800
changeset 341454 aa6dfc22160fdd7ee33362b374d0bfd2b7bb8bb9
parent 341453 d0174f989cfd222d838f80d1572c1f40866e8f42
child 341455 181b7f327b53edd3814e8eb1669a6ad518d5ee57
push id86727
push userkwierso@gmail.com
push dateThu, 09 Feb 2017 00:21:26 +0000
treeherdermozilla-inbound@55a4f5189115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1336501
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1336501 - Sync shield-recipe-client from GitHub (ad0f45e) r=Gijs MozReview-Commit-ID: KiDjjs2qpk5
browser/extensions/shield-recipe-client/bootstrap.js
browser/extensions/shield-recipe-client/lib/CleanupManager.jsm
browser/extensions/shield-recipe-client/lib/EnvExpressions.jsm
browser/extensions/shield-recipe-client/lib/LogManager.jsm
browser/extensions/shield-recipe-client/lib/NormandyDriver.jsm
browser/extensions/shield-recipe-client/test/browser/browser_EnvExpressions.js
browser/extensions/shield-recipe-client/test/browser/browser_NormandyDriver.js
--- a/browser/extensions/shield-recipe-client/bootstrap.js
+++ b/browser/extensions/shield-recipe-client/bootstrap.js
@@ -2,26 +2,34 @@
  * 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 {utils: Cu} = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "LogManager",
+  "resource://shield-recipe-client/lib/LogManager.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "RecipeRunner",
+  "resource://shield-recipe-client/lib/RecipeRunner.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CleanupManager",
+  "resource://shield-recipe-client/lib/CleanupManager.jsm");
 
 const REASONS = {
   APP_STARTUP: 1,      // The application is starting up.
   APP_SHUTDOWN: 2,     // The application is shutting down.
   ADDON_ENABLE: 3,     // The add-on is being enabled.
   ADDON_DISABLE: 4,    // The add-on is being disabled. (Also sent during uninstallation)
   ADDON_INSTALL: 5,    // The add-on is being installed.
   ADDON_UNINSTALL: 6,  // The add-on is being uninstalled.
   ADDON_UPGRADE: 7,    // The add-on is being upgraded.
-  ADDON_DOWNGRADE: 8,  //The add-on is being downgraded.
+  ADDON_DOWNGRADE: 8,  // The add-on is being downgraded.
 };
 
 const PREF_BRANCH = "extensions.shield-recipe-client.";
 const DEFAULT_PREFS = {
   api_url: "https://self-repair.mozilla.org/api/v1",
   dev_mode: false,
   enabled: true,
   startup_delay_seconds: 300,
@@ -48,29 +56,25 @@ this.install = function() {
 this.startup = function() {
   setDefaultPrefs();
 
   if (!shouldRun) {
     return;
   }
 
   // Setup logging and listen for changes to logging prefs
-  Cu.import("resource://shield-recipe-client/lib/LogManager.jsm");
   LogManager.configure(Services.prefs.getIntPref(PREF_LOGGING_LEVEL));
   Preferences.observe(PREF_LOGGING_LEVEL, LogManager.configure);
+  CleanupManager.addCleanupHandler(
+    () => Preferences.ignore(PREF_LOGGING_LEVEL, LogManager.configure));
 
-  Cu.import("resource://shield-recipe-client/lib/RecipeRunner.jsm");
   RecipeRunner.init();
 };
 
 this.shutdown = function(data, reason) {
-  Preferences.ignore(PREF_LOGGING_LEVEL, LogManager.configure);
-
-  Cu.import("resource://shield-recipe-client/lib/CleanupManager.jsm");
-
   CleanupManager.cleanup();
 
   if (reason === REASONS.ADDON_DISABLE || reason === REASONS.ADDON_UNINSTALL) {
     Services.prefs.setBoolPref(PREF_SELF_SUPPORT_ENABLED, true);
   }
 
   const modules = [
     "lib/CleanupManager.jsm",
--- a/browser/extensions/shield-recipe-client/lib/CleanupManager.jsm
+++ b/browser/extensions/shield-recipe-client/lib/CleanupManager.jsm
@@ -1,16 +1,15 @@
 /* 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 {utils: Cu} = Components;
-
 this.EXPORTED_SYMBOLS = ["CleanupManager"];
 
 const cleanupHandlers = new Set();
 
 this.CleanupManager = {
   addCleanupHandler(handler) {
     cleanupHandlers.add(handler);
   },
--- a/browser/extensions/shield-recipe-client/lib/EnvExpressions.jsm
+++ b/browser/extensions/shield-recipe-client/lib/EnvExpressions.jsm
@@ -1,16 +1,17 @@
 /* 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/Services.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/TelemetryArchive.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://shield-recipe-client/lib/Sampling.jsm");
 
 const {generateUUID} = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
 
 this.EXPORTED_SYMBOLS = ["EnvExpressions"];
@@ -69,19 +70,21 @@ this.EnvExpressions = {
       id = generateUUID().toString().slice(1, -1);
       prefs.setCharPref("user_id", id);
     }
     return id;
   },
 
   eval(expr, extraContext = {}) {
     // First clone the extra context
-    const context = Object.assign({}, extraContext);
+    const context = Object.assign({normandy: {}}, extraContext);
     // jexl handles promises, so it is fine to include them in this data.
     context.telemetry = EnvExpressions.getLatestTelemetry();
-    context.normandy = context.normandy || {};
-    context.normandy.userId = EnvExpressions.getUserId();
+
+    context.normandy = Object.assign(context.normandy, {
+      userId: EnvExpressions.getUserId(),
+      distribution: Preferences.get("distribution.id", "default"),
+    });
 
     const onelineExpr = expr.replace(/[\t\n\r]/g, " ");
-
     return jexl.eval(onelineExpr, context);
   },
 };
--- a/browser/extensions/shield-recipe-client/lib/LogManager.jsm
+++ b/browser/extensions/shield-recipe-client/lib/LogManager.jsm
@@ -4,17 +4,17 @@
 
 "use strict";
 
 const {utils: Cu} = Components;
 Cu.import("resource://gre/modules/Log.jsm");
 
 this.EXPORTED_SYMBOLS = ["LogManager"];
 
-const ROOT_LOGGER_NAME = "extensions.shield-recipe-client"
+const ROOT_LOGGER_NAME = "extensions.shield-recipe-client";
 let rootLogger = null;
 
 this.LogManager = {
   /**
    * Configure the root logger for the Recipe Client. Must be called at
    * least once before using any loggers created via getLogger.
    * @param {Number} loggingLevel
    *        Logging level to use as defined in Log.jsm
--- a/browser/extensions/shield-recipe-client/lib/NormandyDriver.jsm
+++ b/browser/extensions/shield-recipe-client/lib/NormandyDriver.jsm
@@ -70,18 +70,22 @@ this.NormandyDriver = function(sandboxMa
 
     client() {
       const appinfo = {
         version: Services.appinfo.version,
         channel: Services.appinfo.defaultUpdateChannel,
         isDefaultBrowser: ShellService.isDefaultBrowser() || null,
         searchEngine: null,
         syncSetup: Preferences.isSet("services.sync.username"),
+        syncDesktopDevices: Preferences.get("services.sync.clients.devices.desktop", 0),
+        syncMobileDevices: Preferences.get("services.sync.clients.devices.mobile", 0),
+        syncTotalDevices: Preferences.get("services.sync.numClients", 0),
         plugins: {},
         doNotTrack: Preferences.get("privacy.donottrackheader.enabled", false),
+        distribution: Preferences.get("distribution.id", "default"),
       };
 
       const searchEnginePromise = new Promise(resolve => {
         Services.search.init(rv => {
           if (Components.isSuccessCode(rv)) {
             appinfo.searchEngine = Services.search.defaultEngine.identifier;
           }
           resolve();
--- a/browser/extensions/shield-recipe-client/test/browser/browser_EnvExpressions.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_EnvExpressions.js
@@ -77,9 +77,18 @@ add_task(function* () {
   Assert.equal(val, "fake id", "userId is pulled from preferences");
 
   // test that it merges context correctly, `userId` comes from the default context, and
   // `injectedValue` comes from us. Expect both to be on the final `normandy` object.
   val = yield EnvExpressions.eval(
     "[normandy.userId, normandy.injectedValue]",
     {normandy: {injectedValue: "injected"}});
   Assert.deepEqual(val, ["fake id", "injected"], "context is correctly merged");
+
+  // distribution id defaults to "default"
+  val = yield EnvExpressions.eval("normandy.distribution");
+  Assert.equal(val, "default", "distribution has a default value");
+
+  // distribution id is in the context
+  yield SpecialPowers.pushPrefEnv({set: [["distribution.id", "funnelcake"]]});
+  val = yield EnvExpressions.eval("normandy.distribution");
+  Assert.equal(val, "funnelcake", "distribution is read from preferences");
 });
--- a/browser/extensions/shield-recipe-client/test/browser/browser_NormandyDriver.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_NormandyDriver.js
@@ -13,8 +13,37 @@ add_task(Utils.withDriver(Assert, functi
   const uuid2 = driver.uuid();
   isnot(uuid1, uuid2, "uuids are unique");
 }));
 
 add_task(Utils.withDriver(Assert, function* userId(driver) {
   // Test that userId is a UUID
   ok(Utils.UUID_REGEX.test(driver.userId), "userId is a uuid");
 }));
+
+add_task(Utils.withDriver(Assert, function* syncDeviceCounts(driver) {
+  let client = yield driver.client();
+  is(client.syncMobileDevices, 0, "syncMobileDevices defaults to zero");
+  is(client.syncDesktopDevices, 0, "syncDesktopDevices defaults to zero");
+  is(client.syncTotalDevices, 0, "syncTotalDevices defaults to zero");
+
+  yield SpecialPowers.pushPrefEnv({
+    set: [
+      ["services.sync.numClients", 9],
+      ["services.sync.clients.devices.mobile", 5],
+      ["services.sync.clients.devices.desktop", 4],
+    ],
+  });
+
+  client = yield driver.client();
+  is(client.syncMobileDevices, 5, "syncMobileDevices is read when set");
+  is(client.syncDesktopDevices, 4, "syncDesktopDevices is read when set");
+  is(client.syncTotalDevices, 9, "syncTotalDevices is read when set");
+}));
+
+add_task(Utils.withDriver(Assert, function* distribution(driver) {
+  let client = yield driver.client();
+  is(client.distribution, "default", "distribution has a default value");
+
+  yield SpecialPowers.pushPrefEnv({set: [["distribution.id", "funnelcake"]]});
+  client = yield driver.client();
+  is(client.distribution, "funnelcake", "distribution is read from preferences");
+}));