Bug 1336501 - Sync shield-recipe-client from GitHub (ad0f45e) r?Gijs
MozReview-Commit-ID: KiDjjs2qpk5
--- 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");
+}));