Bug 1371762 Part 2 Treat webextension experiments as legacy
MozReview-Commit-ID: ATa0DXnV2au
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -257,17 +257,22 @@ const CHROME_TYPES = new Set([
const SIGNED_TYPES = new Set([
"apiextension",
"extension",
"experiment",
"webextension",
"webextension-theme",
]);
-const ALL_TYPES = new Set([
+const LEGACY_TYPES = new Set([
+ "apiextension",
+ "extension",
+]);
+
+const ALL_EXTERNAL_TYPES = new Set([
"dictionary",
"extension",
"experiment",
"locale",
"theme",
]);
// Whether add-on signing is required.
@@ -830,18 +835,18 @@ function isUsableAddon(aAddon) {
let active = XPIProvider.activeAddons.get(id);
return active && !active.disable;
};
if (aAddon.dependencies.some(id => !isActive(id)))
return false;
}
- if (!AddonSettings.ALLOW_LEGACY_EXTENSIONS &&
- aAddon.type == "extension" && !aAddon._installLocation.isSystem &&
+ if (!AddonSettings.ALLOW_LEGACY_EXTENSIONS && LEGACY_TYPES.has(aAddon.type) &&
+ !aAddon._installLocation.isSystem &&
aAddon.signedState !== AddonManager.SIGNEDSTATE_PRIVILEGED) {
logger.warn(`disabling legacy extension ${aAddon.id}`);
return false;
}
if (!ALLOW_NON_MPC && aAddon.type == "extension" &&
aAddon.multiprocessCompatible !== true) {
logger.warn(`disabling ${aAddon.id} since it is not multiprocess compatible`);
@@ -3583,17 +3588,17 @@ this.XPIProvider = {
*
* @param aTypes
* An array of types to fetch. Can be null to get all types.
* @param aCallback
* A callback to pass an array of Addons to
*/
getAddonsByTypes(aTypes, aCallback) {
let typesToGet = getAllAliasesForTypes(aTypes);
- if (typesToGet && !typesToGet.some(type => ALL_TYPES.has(type))) {
+ if (typesToGet && !typesToGet.some(type => ALL_EXTERNAL_TYPES.has(type))) {
aCallback([]);
return;
}
XPIDatabase.getVisibleAddons(typesToGet, function(aAddons) {
aCallback(aAddons.map(a => a.wrapper));
});
},
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_legacy.js
@@ -0,0 +1,131 @@
+
+const LEGACY_PREF = "extensions.legacy.enabled";
+
+createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
+startupManager();
+
+add_task(async function test_disable() {
+ let legacy = [
+ {
+ id: "bootstrap@tests.mozilla.org",
+ name: "Bootstrap add-on",
+ version: "1.0",
+ bootstrap: true,
+ multiprocessCompatible: true,
+ },
+ {
+ id: "apiexperiment@tests.mozilla.org",
+ name: "WebExtension Experiment",
+ version: "1.0",
+ type: 256,
+ },
+ ];
+
+ let nonLegacy = [
+ {
+ id: "webextension@tests.mozilla.org",
+ manifest: {
+ applications: {gecko: {id: "webextension@tests.mozilla.org"}},
+ },
+ },
+ {
+ id: "privileged@tests.mozilla.org",
+ name: "Privileged Bootstrap add-on",
+ version: "1.0",
+ bootstrap: true,
+ multiprocessCompatible: true,
+ },
+ {
+ id: "langpack@tests.mozilla.org",
+ name: "Test Langpack",
+ version: "1.0",
+ type: "8",
+ },
+ {
+ id: "dictionary@tests.mozilla.org",
+ name: "Test Dictionary",
+ version: "1.0",
+ type: "64",
+ }
+ ];
+
+ function makeXPI(info) {
+ if (info.manifest) {
+ return createTempWebExtensionFile(info);
+ }
+
+ return createTempXPIFile(Object.assign({}, info, {
+ targetApplications: [{
+ id: "xpcshell@tests.mozilla.org",
+ minVersion: "1",
+ maxVersion: "1"
+ }],
+ }));
+ }
+
+ AddonTestUtils.usePrivilegedSignatures = id => id.startsWith("privileged");
+
+ // Start out with legacy extensions disabled, installing non-legacy
+ // extensions should succeed.
+ Services.prefs.setBoolPref(LEGACY_PREF, false);
+ let installs = await Promise.all(nonLegacy.map(info => {
+ let xpi = makeXPI(info);
+ return AddonManager.getInstallForFile(xpi);
+ }));
+ await promiseCompleteAllInstalls(installs);
+ for (let install of installs) {
+ do_check_eq(install.state, AddonManager.STATE_INSTALLED);
+ do_check_eq(install.error, 0);
+ }
+ let addons = await AddonManager.getAddonsByIDs(nonLegacy.map(a => a.id));
+ for (let addon of addons) {
+ do_check_eq(addon.appDisabled, false);
+ }
+
+ // And installing legacy extensions should fail
+ let legacyXPIs = legacy.map(makeXPI);
+ installs = await Promise.all(legacyXPIs.map(xpi => AddonManager.getInstallForFile(xpi)));
+
+ // Yuck, the AddonInstall API is atrocious. Installs of incompatible
+ // extensions are detected when the install reaches the DOWNLOADED state
+ // and the install is abandoned at that point. Since this is a local file
+ // install we just start out in the DONWLOADED state.
+ for (let install of installs) {
+ do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
+ do_check_eq(install.addon.appDisabled, true);
+ }
+
+ // Now enable legacy extensions, and we should be able to install
+ // the legacy extensions.
+ Services.prefs.setBoolPref(LEGACY_PREF, true);
+ installs = await Promise.all(legacyXPIs.map(xpi => AddonManager.getInstallForFile(xpi)));
+ for (let install of installs) {
+ do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
+ do_check_eq(install.addon.appDisabled, false);
+ }
+ await promiseCompleteAllInstalls(installs);
+ for (let install of installs) {
+ do_check_eq(install.state, AddonManager.STATE_INSTALLED);
+ do_check_eq(install.error, 0);
+ }
+ addons = await AddonManager.getAddonsByIDs(legacy.map(a => a.id));
+ for (let addon of addons) {
+ do_check_eq(addon.appDisabled, false);
+ }
+
+ // Flip the preference back, the legacy extensions should become disabled
+ // but non-legacy extensions should remain enabled.
+ Services.prefs.setBoolPref(LEGACY_PREF, false);
+ addons = await AddonManager.getAddonsByIDs(nonLegacy.map(a => a.id));
+ for (let addon of addons) {
+ do_check_eq(addon.appDisabled, false);
+ addon.uninstall();
+ }
+ addons = await AddonManager.getAddonsByIDs(legacy.map(a => a.id));
+ for (let addon of addons) {
+ do_check_eq(addon.appDisabled, true);
+ addon.uninstall();
+ }
+
+ Services.prefs.clearUserPref(LEGACY_PREF);
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
@@ -234,16 +234,17 @@ tags = blocklist
[test_install_icons.js]
# Bug 676992: test consistently hangs on Android
skip-if = os == "android"
[test_install_strictcompat.js]
# Bug 676992: test consistently hangs on Android
skip-if = os == "android"
run-sequentially = Uses hardcoded ports in xpi files.
[test_isDebuggable.js]
+[test_legacy.js]
[test_locale.js]
[test_locked.js]
[test_locked2.js]
[test_locked_strictcompat.js]
[test_manifest.js]
[test_mapURIToAddonID.js]
# Same as test_bootstrap.js
skip-if = os == "android"