diff --git a/browser/experiments/Experiments.jsm b/browser/experiments/Experiments.jsm index 369dc04cedb4..fd3b6a5e9006 100644 --- a/browser/experiments/Experiments.jsm +++ b/browser/experiments/Experiments.jsm @@ -611,8 +611,6 @@ Experiments.Experiments.prototype = { return this._run(); }, - // START OF ADD-ON LISTENERS - onDisabled: function (addon) { gLogger.trace("Experiments::onDisabled() - addon id: " + addon.id); if (addon.id == this._pendingUninstall) { @@ -638,8 +636,6 @@ Experiments.Experiments.prototype = { this.disableExperiment(); }, - // END OF ADD-ON LISTENERS. - _getExperimentByAddonId: function (addonId) { for (let [, entry] of this._experiments) { if (entry._addonId === addonId) { @@ -1380,9 +1376,8 @@ Experiments.ExperimentEntry.prototype = { deferred.reject(new Error(message)); }; - let entry = this; let listener = { - onDownloadEnded: function (install) { + onDownloadEnded: install => { gLogger.trace("ExperimentEntry::_installAddon() - onDownloadEnded for " + this.id); if (install.existingAddon) { @@ -1393,9 +1388,9 @@ Experiments.ExperimentEntry.prototype = { gLogger.error("ExperimentEntry::_installAddon() - onDownloadEnded, wrong addon type"); install.cancel(); } - }.bind(entry), + }, - onInstallStarted: function (install) { + onInstallStarted: install => { gLogger.trace("ExperimentEntry::_installAddon() - onInstallStarted for " + this.id); if (install.existingAddon) { @@ -1406,12 +1401,9 @@ Experiments.ExperimentEntry.prototype = { gLogger.error("ExperimentEntry::_installAddon() - onInstallStarted, wrong addon type"); return false; } + }, - // Experiment add-ons default to userDisabled = true. - install.addon.userDisabled = false; - }.bind(entry), - - onInstallEnded: function (install) { + onInstallEnded: install => { gLogger.trace("ExperimentEntry::_installAddon() - install ended for " + this.id); this._lastChangedDate = this._policy.now(); this._startDate = this._policy.now(); @@ -1427,14 +1419,14 @@ Experiments.ExperimentEntry.prototype = { this._homepageURL = addon.homepageURL || ""; deferred.resolve(); - }.bind(entry), - - onDownloadCancelled: failureHandler.bind(entry), - onDownloadFailed: failureHandler.bind(entry), - onInstallCancelled: failureHandler.bind(entry), - onInstallFailed: failureHandler.bind(entry), + }, }; + ["onDownloadCancelled", "onDownloadFailed", "onInstallCancelled", "onInstallFailed"] + .forEach(what => { + listener[what] = install => failureHandler(install, what) + }); + install.addListener(listener); install.install(); diff --git a/toolkit/mozapps/extensions/AddonManager.jsm b/toolkit/mozapps/extensions/AddonManager.jsm index eb0fc7039057..46da6db81543 100644 --- a/toolkit/mozapps/extensions/AddonManager.jsm +++ b/toolkit/mozapps/extensions/AddonManager.jsm @@ -2317,25 +2317,7 @@ this.AddonManagerPrivate = { return { done: () => this.recordSimpleMeasure(aName, Date.now() - startTime) }; - }, - - /** - * Helper to call update listeners when no update is available. - * - * This can be used as an implementation for Addon.findUpdates() when - * no update mechanism is available. - */ - callNoUpdateListeners: function (addon, listener, reason, appVersion, platformVersion) { - if ("onNoCompatibilityUpdateAvailable" in listener) { - safeCall(listener.onNoCompatibilityUpdateAvailable, addon); - } - if ("onNoUpdateAvailable" in listener) { - safeCall(listener.onNoUpdateAvailable, addon); - } - if ("onUpdateFinished" in listener) { - safeCall(listener.onUpdateFinished, addon); - } - }, + } }; /** diff --git a/toolkit/mozapps/extensions/LightweightThemeManager.jsm b/toolkit/mozapps/extensions/LightweightThemeManager.jsm index 615f792b6e4c..8c9f30492d3f 100644 --- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm +++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm @@ -508,7 +508,12 @@ function AddonWrapper(aTheme) { }; this.findUpdates = function AddonWrapper_findUpdates(listener, reason, appVersion, platformVersion) { - AddonManagerPrivate.callNoUpdateListeners(this, listener, reason, appVersion, platformVersion); + if ("onNoCompatibilityUpdateAvailable" in listener) + listener.onNoCompatibilityUpdateAvailable(this); + if ("onNoUpdateAvailable" in listener) + listener.onNoUpdateAvailable(this); + if ("onUpdateFinished" in listener) + listener.onUpdateFinished(this); }; } diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 030cd253587a..e0607d964a1a 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -908,11 +908,6 @@ function loadManifestFromRDF(aUri, aStream) { addon.userDisabled = !!LightweightThemeManager.currentTheme || addon.internalName != XPIProvider.selectedSkin; } - // Experiments are disabled by default. It is up to the Experiments Manager - // to enable them (it drives installation). - else if (addon.type == "experiment") { - addon.userDisabled = true; - } else { addon.userDisabled = false; addon.softDisabled = addon.blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED; @@ -920,17 +915,6 @@ function loadManifestFromRDF(aUri, aStream) { 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; - addon.updateKey = null; - - addon.targetApplications = []; - addon.targetPlatforms = []; - } - // Load the storage service before NSS (nsIRandomGenerator), // to avoid a SQLite initialization error (bug 717904). let storage = Services.storage; @@ -2087,19 +2071,8 @@ var XPIProvider = { * Persists changes to XPIProvider.bootstrappedAddons to its store (a pref). */ persistBootstrappedAddons: function XPI_persistBootstrappedAddons() { - // Experiments are disabled upon app load, so don't persist references. - let filtered = {}; - for (let id in this.bootstrappedAddons) { - let entry = this.bootstrappedAddons[id]; - if (entry.type == "experiment") { - continue; - } - - filtered[id] = entry; - } - Services.prefs.setCharPref(PREF_BOOTSTRAP_ADDONS, - JSON.stringify(filtered)); + JSON.stringify(this.bootstrappedAddons)); }, /** @@ -4254,16 +4227,12 @@ var XPIProvider = { // no onDisabling/onEnabling is sent - so send a onPropertyChanged. let appDisabledChanged = aAddon.appDisabled != appDisabled; - // Update the properties in the database. - // We never persist this for experiments because the disabled flags - // are controlled by the Experiments Manager. - if (aAddon.type != "experiment") { - XPIDatabase.setAddonProperties(aAddon, { - userDisabled: aUserDisabled, - appDisabled: appDisabled, - softDisabled: aSoftDisabled - }); - } + // Update the properties in the database + XPIDatabase.setAddonProperties(aAddon, { + userDisabled: aUserDisabled, + appDisabled: appDisabled, + softDisabled: aSoftDisabled + }); if (appDisabledChanged) { AddonManagerPrivate.callAddonListeners("onPropertyChanged", @@ -6045,17 +6014,6 @@ AddonInternal.prototype = { }, isCompatibleWith: function AddonInternal_isCompatibleWith(aAppVersion, aPlatformVersion) { - // 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 (this.type == "experiment") { - return true; - } - let app = this.matchingTargetApplication; if (!app) return false; @@ -6440,11 +6398,6 @@ function AddonWrapper(aAddon) { return aAddon.applyBackgroundUpdates; }); this.__defineSetter__("applyBackgroundUpdates", function AddonWrapper_applyBackgroundUpdatesSetter(val) { - if (this.type == "experiment") { - logger.warn("Setting applyBackgroundUpdates on an experiment is not supported."); - return; - } - if (val != AddonManager.AUTOUPDATE_DEFAULT && val != AddonManager.AUTOUPDATE_DISABLE && val != AddonManager.AUTOUPDATE_ENABLE) { @@ -6545,33 +6498,22 @@ function AddonWrapper(aAddon) { if (!(aAddon.inDatabase)) return permissions; - // Experiments can only be uninstalled. An uninstall reflects the user - // intent of "disable this experiment." This is partially managed by the - // experiments manager. - if (aAddon.type == "experiment") { - return AddonManager.PERM_CAN_UNINSTALL; - } - if (!aAddon.appDisabled) { - if (this.userDisabled) { + if (this.userDisabled) permissions |= AddonManager.PERM_CAN_ENABLE; - } - else if (aAddon.type != "theme") { + else if (aAddon.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 (!aAddon._installLocation.locked && !aAddon.pendingUninstall) { // Add-ons that are installed by a file link cannot be upgraded - if (!aAddon._installLocation.isLinkedAddon(aAddon.id)) { + if (!aAddon._installLocation.isLinkedAddon(aAddon.id)) permissions |= AddonManager.PERM_CAN_UPGRADE; - } permissions |= AddonManager.PERM_CAN_UNINSTALL; } - return permissions; }); @@ -6653,14 +6595,6 @@ function AddonWrapper(aAddon) { }; this.findUpdates = function AddonWrapper_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(aAddon, aListener, aReason, aAppVersion, aPlatformVersion); }; diff --git a/toolkit/mozapps/extensions/test/addons/test_experiment1/install.rdf b/toolkit/mozapps/extensions/test/addons/test_experiment1/install.rdf deleted file mode 100644 index 9508b1562e78..000000000000 --- a/toolkit/mozapps/extensions/test/addons/test_experiment1/install.rdf +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - experiment1@tests.mozilla.org - 1.0 - 128 - true - - - Test Experiment 1 - Test Description - - - diff --git a/toolkit/mozapps/extensions/test/browser/browser_experiments.js b/toolkit/mozapps/extensions/test/browser/browser_experiments.js index 2f760acc3f6e..6c2b771897aa 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_experiments.js +++ b/toolkit/mozapps/extensions/test/browser/browser_experiments.js @@ -50,7 +50,8 @@ add_test(function testActiveExperiment() { install_addon("addons/browser_experiment1.xpi", (addon) => { gInstalledAddons.push(addon); - Assert.ok(addon.userDisabled, "Add-on is disabled upon initial install."); + // This may change if we remove compatibility checking from experiments. + // Putting this check here so a test fails if preconditions change. Assert.equal(addon.isActive, false, "Add-on is not active."); Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible."); @@ -132,22 +133,3 @@ add_test(function testOpenPreferences() { EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow); }); }); - -add_test(function testButtonPresence() { - gCategoryUtilities.openType("experiment", (win) => { - let item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org"); - Assert.ok(item, "Got add-on element."); - - let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn"); - // Corresponds to the uninstall permission. - is_element_visible(el, "Remove button is visible."); - // Corresponds to lack of disable permission. - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "disable-btn"); - is_element_hidden(el, "Disable button not visible."); - // Corresponds to lack of enable permission. - el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "enable-btn"); - is_element_hidden(el, "Enable button not visible."); - - run_next_test(); - }); -}); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_experiment.js b/toolkit/mozapps/extensions/test/xpcshell/test_experiment.js deleted file mode 100644 index 72efdb32b3ad..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/test_experiment.js +++ /dev/null @@ -1,89 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -let scope = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm"); -const XPIProvider = scope.XPIProvider; - -function run_test() { - createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); - startupManager(); - - run_next_test(); -} - -add_test(function test_experiment() { - AddonManager.getInstallForFile(do_get_addon("test_experiment1"), (install) => { - completeAllInstalls([install], () => { - AddonManager.getAddonByID("experiment1@tests.mozilla.org", (addon) => { - Assert.ok(addon, "Addon is found."); - - Assert.ok(addon.userDisabled, "Experiments are userDisabled by default."); - 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, - "Permissions are minimal."); - - // 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."); - - run_next_test(); - }); - }); - }); -}); - -// Changes to userDisabled should not be persisted to the database. -add_test(function test_userDisabledNotPersisted() { - AddonManager.getAddonByID("experiment1@tests.mozilla.org", (addon) => { - Assert.ok(addon, "Addon is found."); - - let listener = { - onEnabled: (addon2) => { - Assert.equal(addon2.id, addon.id, "Changed add-on matches expected."); - Assert.ok(addon2.isActive, "Add-on is no longer disabled."); - - Assert.ok("experiment1@tests.mozilla.org" in XPIProvider.bootstrappedAddons, - "Experiment add-on listed in XPIProvider bootstrapped list."); - - AddonManager.getAddonByID("experiment1@tests.mozilla.org", (addon) => { - Assert.ok(addon, "Add-on retrieved."); - Assert.ok(addon.userDisabled, "Add-on is disabled according to database."); - - restartManager(); - let persisted = JSON.parse(Services.prefs.getCharPref("extensions.bootstrappedAddons")); - Assert.ok(!("experiment1@tests.mozilla.org" in persisted), - "Experiment add-on not persisted to bootstrappedAddons."); - - AddonManager.getAddonByID("experiment1@tests.mozilla.org", (addon) => { - Assert.ok(addon, "Add-on retrieved."); - Assert.ok(addon.userDisabled, "Add-on is disabled after restart."); - - run_next_test(); - }); - }); - }, - }; - - AddonManager.addAddonListener(listener); - addon.userDisabled = false; - }); -}); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_shutdown.js b/toolkit/mozapps/extensions/test/xpcshell/test_shutdown.js index 6bf3f27d890a..c9c67d8138b5 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_shutdown.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_shutdown.js @@ -17,8 +17,7 @@ const IGNORE_PRIVATE = ["AddonAuthor", "AddonCompatibilityOverride", "addStartupChange", "removeStartupChange", "recordTimestamp", "recordSimpleMeasure", "recordException", "getSimpleMeasures", "simpleTimer", - "setTelemetryDetails", "getTelemetryDetails", - "callNoUpdateListeners"]; + "setTelemetryDetails", "getTelemetryDetails"]; function test_functions() { for (let prop in AddonManager) { diff --git a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini index 644dbdb128b3..d0ced7767e9e 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini @@ -163,7 +163,6 @@ fail-if = os == "android" # Bug 676992: test consistently hangs on Android skip-if = os == "android" [test_error.js] -[test_experiment.js] [test_filepointer.js] # Bug 676992: test consistently hangs on Android skip-if = os == "android"