Bug 1450801 Part 2: Remove AddonManager support for telemetry experiments
MozReview-Commit-ID: FkQd7Ia5Tv4
--- a/browser/experiments/test/xpcshell/xpcshell.ini
+++ b/browser/experiments/test/xpcshell/xpcshell.ini
@@ -19,12 +19,13 @@ generated-files =
[test_activate.js]
[test_api.js]
[test_cache.js]
[test_cacherace.js]
[test_conditions.js]
[test_disableExperiments.js]
[test_fetch.js]
[test_telemetry.js]
+skip-if = true # To be removed soon in bug 1420908
[test_telemetry_disabled.js]
[test_previous_provider.js]
[test_upgrade.js]
[test_nethang_bug1012924.js]
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -133,35 +133,34 @@ const PROP_METADATA = ["id", "versi
"optionsURL", "optionsType", "aboutURL",
"iconURL", "icon64URL"];
const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
// Map new string type identifiers to old style nsIUpdateItem types.
// Retired values:
+// 8 = locale
// 32 = multipackage xpi file
-// 8 = locale
+// 128 = experiment
const TYPES = {
extension: 2,
theme: 4,
dictionary: 64,
- experiment: 128,
apiextension: 256,
};
const COMPATIBLE_BY_DEFAULT_TYPES = {
extension: true,
dictionary: true,
};
const RESTARTLESS_TYPES = new Set([
"apiextension",
"dictionary",
- "experiment",
"webextension",
"webextension-theme",
]);
// This is a random number array that can be used as "salt" when generating
// an automatic ID based on the directory path of an add-on. It will prevent
// someone from creating an ID for a permanent add-on that could be replaced
// by a temporary add-on (because that would be confusing, I guess).
@@ -636,34 +635,23 @@ async function loadManifestFromRDF(aUri,
}
// A theme's userDisabled value is true if the theme is not the selected skin
// or if there is an active lightweight theme. We ignore whether softblocking
// is in effect since it would change the active theme.
if (isTheme(addon.type)) {
addon.userDisabled = !!LightweightThemeManager.currentTheme ||
addon.internalName != DEFAULT_SKIN;
- } else if (addon.type == "experiment") {
- // Experiments are disabled by default. It is up to the Experiments Manager
- // to enable them (it drives installation).
- addon.userDisabled = true;
} else {
addon.userDisabled = false;
}
addon.softDisabled = addon.blocklistState == nsIBlocklistService.STATE_SOFTBLOCKED;
addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
- // Experiments are managed and updated through an external "experiments
- // manager." So disable some built-in mechanisms.
- if (addon.type == "experiment") {
- addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
- addon.updateURL = null;
- }
-
// icons will be filled by the calling function
addon.icons = {};
addon.userPermissions = null;
return addon;
}
function defineSyncGUID(aAddon) {
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -196,38 +196,35 @@ const TYPE_ALIASES = {
"apiextension": "extension",
"webextension": "extension",
"webextension-theme": "theme",
"webextension-langpack": "locale",
};
const CHROME_TYPES = new Set([
"extension",
- "experiment",
]);
const SIGNED_TYPES = new Set([
"apiextension",
"extension",
- "experiment",
"webextension",
"webextension-langpack",
"webextension-theme",
]);
const LEGACY_TYPES = new Set([
"apiextension",
"extension",
"theme",
]);
const ALL_EXTERNAL_TYPES = new Set([
"dictionary",
"extension",
- "experiment",
"locale",
"theme",
]);
// Whether add-on signing is required.
function mustSign(aType) {
if (!SIGNED_TYPES.has(aType))
return false;
@@ -809,26 +806,16 @@ function isUsableAddon(aAddon) {
return false;
}
if (aAddon.blocklistState == nsIBlocklistService.STATE_BLOCKED) {
logger.warn(`Add-on ${aAddon.id} is blocklisted.`);
return false;
}
- // Experiments are installed through an external mechanism that
- // limits target audience to compatible clients. We trust it knows what
- // it's doing and skip compatibility checks.
- //
- // This decision does forfeit defense in depth. If the experiments system
- // is ever wrong about targeting an add-on to a specific application
- // or platform, the client will likely see errors.
- if (aAddon.type == "experiment")
- return true;
-
if (AddonManager.checkUpdateSecurity && !aAddon.providesUpdatesSecurely) {
logger.warn(`Updates for add-on ${aAddon.id} must be provided over HTTPS.`);
return false;
}
if (!aAddon.isPlatformCompatible) {
logger.warn(`Add-on ${aAddon.id} is not compatible with platform.`);
@@ -1357,19 +1344,17 @@ class XPIStateLocation extends Map {
json.path = this.path;
}
if (STARTUP_MTIME_SCOPES.includes(this.name)) {
json.checkStartupModifications = true;
}
for (let [id, addon] of this.entries()) {
- if (addon.type != "experiment") {
- json.addons[id] = addon;
- }
+ json.addons[id] = addon;
}
return json;
}
get hasStaged() {
for (let key in this.staged) {
return true;
}
@@ -3522,22 +3507,19 @@ var XPIProvider = {
* An array of types to fetch. Can be null to get all types.
* @returns {Promise<Array<Addon>>}
*/
getActiveAddons(aTypes) {
// If we already have the database loaded, returning full info is fast.
if (this.isDBLoaded) {
return new Promise(resolve => {
this.getAddonsByTypes(aTypes, addons => {
- // The thing with experiments is an ugly hack but we want
- // Experiments.jsm to use this interface instead of getAddonsByTypes.
- // They'll go away at some point and we can forget this ever happened.
- resolve({addons: addons.filter(addon => addon.isActive ||
- (addon.type == "experiment" && !addon.appDisabled)),
- fullData: true
+ resolve({
+ addons: addons.filter(addon => addon.isActive),
+ fullData: true,
});
});
});
}
// Construct addon-like objects with the information we already
// have in memory.
if (!XPIStates.db) {
@@ -4709,22 +4691,20 @@ AddonInternal.prototype = {
} else if (this.type != "theme") {
permissions |= AddonManager.PERM_CAN_DISABLE;
}
}
// Add-ons that are in locked install locations, or are pending uninstall
// cannot be upgraded or uninstalled
if (!this._installLocation.locked && !this.pendingUninstall) {
- // Experiments cannot be upgraded.
// System add-on upgrades are triggered through a different mechanism (see updateSystemAddons())
let isSystem = this._installLocation.isSystem;
// Add-ons that are installed by a file link cannot be upgraded.
- if (this.type != "experiment" &&
- !this._installLocation.isLinkedAddon(this.id) && !isSystem) {
+ if (!this._installLocation.isLinkedAddon(this.id) && !isSystem) {
permissions |= AddonManager.PERM_CAN_UPGRADE;
}
permissions |= AddonManager.PERM_CAN_UNINSTALL;
}
if (Services.policies &&
!Services.policies.isAllowed(`modify-extension:${this.id}`)) {
@@ -4895,21 +4875,16 @@ AddonWrapper.prototype = {
return null;
},
get applyBackgroundUpdates() {
return addonFor(this).applyBackgroundUpdates;
},
set applyBackgroundUpdates(val) {
let addon = addonFor(this);
- if (this.type == "experiment") {
- logger.warn("Setting applyBackgroundUpdates on an experiment is not supported.");
- return addon.applyBackgroundUpdates;
- }
-
if (val != AddonManager.AUTOUPDATE_DEFAULT &&
val != AddonManager.AUTOUPDATE_DISABLE &&
val != AddonManager.AUTOUPDATE_ENABLE) {
val = val ? AddonManager.AUTOUPDATE_DEFAULT :
AddonManager.AUTOUPDATE_DISABLE;
}
if (val == addon.applyBackgroundUpdates)
@@ -5114,24 +5089,16 @@ AddonWrapper.prototype = {
},
cancelUninstall() {
let addon = addonFor(this);
XPIProvider.cancelUninstallAddon(addon);
},
findUpdates(aListener, aReason, aAppVersion, aPlatformVersion) {
- // Short-circuit updates for experiments because updates are handled
- // through the Experiments Manager.
- if (this.type == "experiment") {
- AddonManagerPrivate.callNoUpdateListeners(this, aListener, aReason,
- aAppVersion, aPlatformVersion);
- return;
- }
-
new UpdateChecker(addonFor(this), aListener, aReason, aAppVersion, aPlatformVersion);
},
// Returns true if there was an update in progress, false if there was no update to cancel
cancelUpdate() {
let addon = addonFor(this);
if (addon._updateCheck) {
addon._updateCheck.cancel();
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -201,26 +201,17 @@ Object.assign(DBAddonInternal.prototype,
});
});
if (wasCompatible != this.isCompatible)
XPIProvider.updateAddonDisabledState(this);
},
toJSON() {
- let jsonData = copyProperties(this, PROP_JSON_FIELDS);
-
- // Experiments are serialized as disabled so they aren't run on the next
- // startup.
- if (this.type == "experiment") {
- jsonData.userDisabled = true;
- jsonData.active = false;
- }
-
- return jsonData;
+ return copyProperties(this, PROP_JSON_FIELDS);
},
get inDatabase() {
return true;
}
});
/**
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/addons/test_experiment1/bootstrap.js
+++ /dev/null
@@ -1,1 +0,0 @@
-ChromeUtils.import("resource://xpcshell-data/BootstrapMonitor.jsm").monitor(this);
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/addons/test_experiment1/install.rdf
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-
-<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>experiment1@tests.mozilla.org</em:id>
- <em:version>1.0</em:version>
- <em:type>128</em:type>
-
- <!-- Front End MetaData -->
- <em:name>Test Experiment 1</em:name>
- <em:description>Test Description</em:description>
-
- </Description>
-</RDF>
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/xpcshell/test_experiment.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const ID = "experiment1@tests.mozilla.org";
-
-var gIsNightly = false;
-
-function getXS() {
- let XPI = ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {});
- return XPI.XPIStates;
-}
-
-function getBootstrappedAddons() {
- let obj = {};
- for (let addon of getXS().bootstrappedAddons()) {
- obj[addon.id] = addon;
- }
- return obj;
-}
-
-function run_test() {
- BootstrapMonitor.init();
- createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
- startupManager();
-
- gIsNightly = isNightlyChannel();
-
- run_next_test();
-}
-
-add_task(async function test_experiment() {
- BootstrapMonitor.checkAddonNotInstalled(ID);
- BootstrapMonitor.checkAddonNotStarted(ID);
-
- await promiseInstallAllFiles([do_get_addon("test_experiment1")]);
-
- BootstrapMonitor.checkAddonInstalled(ID, "1.0");
- BootstrapMonitor.checkAddonNotStarted(ID);
-
- let addon = await promiseAddonByID(ID);
- Assert.ok(addon, "Addon is found.");
-
- Assert.ok(addon.userDisabled, "Experiments are userDisabled by default.");
- Assert.ok(!addon.appDisabled, "Experiments are not appDisabled by compatibility.");
- Assert.equal(addon.isActive, false, "Add-on is not active.");
- Assert.equal(addon.updateURL, null, "No updateURL for experiments.");
- Assert.equal(addon.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE,
- "Background updates are disabled.");
- Assert.equal(addon.permissions, AddonManager.PERM_CAN_UNINSTALL + AddonManager.PERM_CAN_ENABLE,
- "Permissions are minimal.");
- Assert.ok(!(addon.pendingOperations & AddonManager.PENDING_ENABLE),
- "Should not be pending enable");
- Assert.ok(!(addon.pendingOperations & AddonManager.PENDING_DISABLE),
- "Should not be pending disable");
-
- // Setting applyBackgroundUpdates should not work.
- addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_ENABLE;
- Assert.equal(addon.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE,
- "Setting applyBackgroundUpdates shouldn't do anything.");
-
- let noCompatibleCalled = false;
- let noUpdateCalled = false;
- let finishedCalled = false;
-
- let listener = {
- onNoCompatibilityUpdateAvailable: () => { noCompatibleCalled = true; },
- onNoUpdateAvailable: () => { noUpdateCalled = true; },
- onUpdateFinished: () => { finishedCalled = true; },
- };
-
- addon.findUpdates(listener, "testing", null, null);
- Assert.ok(noCompatibleCalled, "Listener called.");
- Assert.ok(noUpdateCalled, "Listener called.");
- Assert.ok(finishedCalled, "Listener called.");
-});
-
-// Changes to userDisabled should not be persisted to the database.
-add_task(async function test_userDisabledNotPersisted() {
- let addon = await promiseAddonByID(ID);
- Assert.ok(addon, "Add-on is found.");
- Assert.ok(addon.userDisabled, "Add-on is user disabled.");
-
- let promise = promiseAddonEvent("onEnabled");
- addon.userDisabled = false;
- let [addon2] = await promise;
-
- BootstrapMonitor.checkAddonInstalled(ID, "1.0");
- BootstrapMonitor.checkAddonStarted(ID, "1.0");
-
- Assert.equal(addon2.id, addon.id, "Changed add-on matches expected.");
- Assert.equal(addon2.userDisabled, false, "Add-on is no longer user disabled.");
- Assert.ok(addon2.isActive, "Add-on is active.");
-
- Assert.ok(ID in getBootstrappedAddons(),
- "Experiment add-on listed in XPIProvider bootstrapped list.");
-
- addon = await promiseAddonByID(ID);
- Assert.ok(addon, "Add-on retrieved.");
- Assert.equal(addon.userDisabled, false, "Add-on is still enabled after API retrieve.");
- Assert.ok(addon.isActive, "Add-on is still active.");
- Assert.ok(!(addon.pendingOperations & AddonManager.PENDING_ENABLE),
- "Should not be pending enable");
- Assert.ok(!(addon.pendingOperations & AddonManager.PENDING_DISABLE),
- "Should not be pending disable");
-
- // Now when we restart the manager the add-on should revert state.
- await promiseRestartManager();
-
- Assert.ok(!(ID in getBootstrappedAddons()),
- "Experiment add-on not persisted to bootstrappedAddons.");
-
- BootstrapMonitor.checkAddonInstalled(ID, "1.0");
- BootstrapMonitor.checkAddonNotStarted(ID);
-
- addon = await promiseAddonByID(ID);
- Assert.ok(addon, "Add-on retrieved.");
- Assert.ok(addon.userDisabled, "Add-on is disabled after restart.");
- Assert.equal(addon.isActive, false, "Add-on is not active after restart.");
- addon.uninstall();
-
- BootstrapMonitor.checkAddonNotInstalled(ID);
- BootstrapMonitor.checkAddonNotStarted(ID);
-});
-
-add_task(async function test_checkCompatibility() {
- if (gIsNightly)
- Services.prefs.setBoolPref("extensions.checkCompatibility.nightly", false);
- else
- Services.prefs.setBoolPref("extensions.checkCompatibility.1", false);
-
- await promiseRestartManager();
-
- await promiseInstallAllFiles([do_get_addon("test_experiment1")]);
- let addon = await promiseAddonByID(ID);
-
- BootstrapMonitor.checkAddonInstalled(ID, "1.0");
- BootstrapMonitor.checkAddonNotStarted(ID);
-
- Assert.ok(addon, "Add-on is found.");
- Assert.ok(addon.userDisabled, "Add-on is user disabled.");
- Assert.ok(!addon.appDisabled, "Add-on is not app disabled.");
-});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -131,19 +131,16 @@ head =
skip-if = appname == "thunderbird"
tags = webextensions
[test_dependencies.js]
[test_distribution.js]
[test_duplicateplugins.js]
# Bug 676992: test consistently hangs on Android
skip-if = os == "android"
[test_error.js]
-[test_experiment.js]
-# Bug 676992: test consistently hangs on Android
-skip-if = os == "android"
[test_ext_management.js]
skip-if = appname == "thunderbird"
tags = webextensions
[test_general.js]
[test_getresource.js]
[test_gfxBlacklist_Device.js]
tags = blocklist
[test_gfxBlacklist_DriverNew.js]