Bug 1356027 Add pref to disable non-MPC extensions
MozReview-Commit-ID: 9TdZf3hnLZl
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4782,16 +4782,17 @@ pref("browser.meta_refresh_when_inactive
// XPInstall prefs
pref("xpinstall.whitelist.required", true);
// Only Firefox requires add-on signatures
pref("xpinstall.signatures.required", false);
pref("extensions.alwaysUnpack", false);
pref("extensions.minCompatiblePlatformVersion", "2.0");
pref("extensions.webExtensionsMinPlatformVersion", "42.0a1");
+pref("extensions.allow-non-mpc-extensions", true);
// Other webextensions prefs
pref("extensions.webextensions.keepStorageOnUninstall", false);
pref("extensions.webextensions.keepUuidOnUninstall", false);
// Redirect basedomain used by identity api
pref("extensions.webextensions.identity.redirectDomain", "extensions.allizom.org");
// Whether or not webextension themes are supported.
pref("extensions.webextensions.themes.enabled", false);
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -127,16 +127,17 @@ const PREF_INSTALL_DISTRO_ADDONS =
const PREF_BRANCH_INSTALLED_ADDON = "extensions.installedDistroAddon.";
const PREF_INTERPOSITION_ENABLED = "extensions.interposition.enabled";
const PREF_SYSTEM_ADDON_SET = "extensions.systemAddonSet";
const PREF_SYSTEM_ADDON_UPDATE_URL = "extensions.systemAddon.update.url";
const PREF_E10S_BLOCK_ENABLE = "extensions.e10sBlocksEnabling";
const PREF_E10S_ADDON_BLOCKLIST = "extensions.e10s.rollout.blocklist";
const PREF_E10S_ADDON_POLICY = "extensions.e10s.rollout.policy";
const PREF_E10S_HAS_NONEXEMPT_ADDON = "extensions.e10s.rollout.hasAddon";
+const PREF_ALLOW_NON_MPC = "extensions.allow-non-mpc-extensions";
const PREF_EM_MIN_COMPAT_APP_VERSION = "extensions.minCompatibleAppVersion";
const PREF_EM_MIN_COMPAT_PLATFORM_VERSION = "extensions.minCompatiblePlatformVersion";
const PREF_CHECKCOMAT_THEMEOVERRIDE = "extensions.checkCompatibility.temporaryThemeOverride_minAppVersion";
const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
const PREF_EM_CERT_CHECKATTRIBUTES = "extensions.hotfix.cert.checkAttributes";
@@ -180,16 +181,18 @@ const RDFURI_INSTALL_MANIFEST_ROOT =
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
const TOOLKIT_ID = "toolkit@mozilla.org";
const XPI_SIGNATURE_CHECK_PERIOD = 24 * 60 * 60;
XPCOMUtils.defineConstant(this, "DB_SCHEMA", 19);
+XPCOMUtils.defineLazyPreferenceGetter(this, "ALLOW_NON_MPC", PREF_ALLOW_NON_MPC);
+
const NOTIFICATION_TOOLBOXPROCESS_LOADED = "ToolboxProcessLoaded";
// Properties that exist in the install manifest
const PROP_METADATA = ["id", "version", "type", "internalName", "updateURL",
"updateKey", "optionsURL", "optionsType", "aboutURL",
"iconURL", "icon64URL"];
const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
@@ -800,16 +803,21 @@ function isUsableAddon(aAddon) {
let active = XPIProvider.activeAddons.get(id);
return active && !active.disable;
};
if (aAddon.dependencies.some(id => !isActive(id)))
return false;
}
+ if (!ALLOW_NON_MPC && aAddon.multiprocessCompatible !== true) {
+ logger.warn(`disabling ${aAddon.id} since it is not multiprocess compatible`);
+ return false;
+ }
+
if (AddonManager.checkCompatibility) {
if (!aAddon.isCompatible) {
logger.warn(`Add-on ${aAddon.id} is not compatible with application version.`);
return false;
}
} else {
let app = aAddon.matchingTargetApplication;
if (!app) {
@@ -2810,16 +2818,17 @@ this.XPIProvider = {
this.enabledAddons = "";
Services.prefs.addObserver(PREF_EM_MIN_COMPAT_APP_VERSION, this);
Services.prefs.addObserver(PREF_EM_MIN_COMPAT_PLATFORM_VERSION, this);
Services.prefs.addObserver(PREF_E10S_ADDON_BLOCKLIST, this);
Services.prefs.addObserver(PREF_E10S_ADDON_POLICY, this);
if (!REQUIRE_SIGNING)
Services.prefs.addObserver(PREF_XPI_SIGNATURES_REQUIRED, this);
+ Services.prefs.addObserver(PREF_ALLOW_NON_MPC, this);
Services.obs.addObserver(this, NOTIFICATION_FLUSH_PERMISSIONS);
// Cu.isModuleLoaded can fail here for external XUL apps where there is
// no chrome.manifest that defines resource://devtools.
if (ResProtocolHandler.hasSubstitution("devtools")) {
if (Cu.isModuleLoaded("resource://devtools/client/framework/ToolboxProcess.jsm")) {
// If BrowserToolboxProcess is already loaded, set the boolean to true
// and do whatever is needed
@@ -4473,16 +4482,17 @@ this.XPIProvider = {
this.updateAddonAppDisabledStates();
break;
case PREF_EM_MIN_COMPAT_PLATFORM_VERSION:
this.minCompatiblePlatformVersion = Preferences.get(PREF_EM_MIN_COMPAT_PLATFORM_VERSION,
null);
this.updateAddonAppDisabledStates();
break;
case PREF_XPI_SIGNATURES_REQUIRED:
+ case PREF_ALLOW_NON_MPC:
this.updateAddonAppDisabledStates();
break;
case PREF_E10S_ADDON_BLOCKLIST:
case PREF_E10S_ADDON_POLICY:
XPIDatabase.updateAddonsBlockingE10s();
break;
}
--- a/toolkit/mozapps/extensions/test/xpcshell/test_multiprocessCompatible.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_multiprocessCompatible.js
@@ -97,16 +97,86 @@ function build_test(multiprocessCompatib
for (let bootstrap of [false, true]) {
for (let multiprocessCompatible of [undefined, false, true]) {
for (let updateMultiprocessCompatible of [undefined, false, true]) {
add_task(build_test(multiprocessCompatible, bootstrap, updateMultiprocessCompatible));
}
}
}
+add_task(async function test_disable() {
+ const PREF = "extensions.allow-non-mpc-extensions";
+ const ID_MPC = "mpc@tests.mozilla.org";
+ const ID_NON_MPC = "non-mpc@tests.mozilla.org";
+
+ let addonData = {
+ name: "Test Add-on",
+ version: "1.0",
+ bootstrap: true,
+ targetApplications: [{
+ id: "xpcshell@tests.mozilla.org",
+ minVersion: "1",
+ maxVersion: "1"
+ }]
+ }
+
+ let xpi1 = createTempXPIFile(Object.assign({
+ id: ID_MPC,
+ multiprocessCompatible: true,
+ }, addonData));
+ let xpi2 = createTempXPIFile(Object.assign({
+ id: ID_NON_MPC,
+ multiprocessCompatible: false,
+ }, addonData));
+
+ async function testOnce(initialAllow) {
+ if (initialAllow !== undefined) {
+ Services.prefs.setBoolPref(PREF, initialAllow);
+ }
+
+ let install1 = await AddonManager.getInstallForFile(xpi1);
+ let install2 = await AddonManager.getInstallForFile(xpi2);
+ await promiseCompleteAllInstalls([install1, install2]);
+
+ let [addon1, addon2] = await AddonManager.getAddonsByIDs([ID_MPC, ID_NON_MPC]);
+ do_check_neq(addon1, null);
+ do_check_eq(addon1.multiprocessCompatible, true);
+ do_check_eq(addon1.appDisabled, false);
+
+ do_check_neq(addon2, null);
+ do_check_eq(addon2.multiprocessCompatible, false);
+ do_check_eq(addon2.appDisabled, initialAllow === false);
+
+ // Flip the allow-non-mpc preference
+ let newValue = (initialAllow === true) ? false : true;
+ Services.prefs.setBoolPref(PREF, newValue);
+
+ // the mpc extension should never become appDisabled
+ do_check_eq(addon1.appDisabled, false);
+
+ // The non-mpc extension should become disabled if we don't allow non-mpc
+ do_check_eq(addon2.appDisabled, !newValue);
+
+ // Flip the pref back and check appDisabled
+ Services.prefs.setBoolPref(PREF, !newValue);
+
+ do_check_eq(addon1.appDisabled, false);
+ do_check_eq(addon2.appDisabled, newValue);
+
+ addon1.uninstall();
+ addon2.uninstall();
+ }
+
+ await testOnce(undefined);
+ await testOnce(true);
+ await testOnce(false);
+
+ Services.prefs.clearUserPref(PREF);
+});
+
function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
startupManager();
// Create and configure the HTTP server.
gServer = new HttpServer();
gServer.registerDirectory("/data/", gTmpD);
gServer.start(-1);