Bug 1356462 Add per-extension notice for non-MPC disabling
MozReview-Commit-ID: KQ69E7B4VPg
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
@@ -22,16 +22,19 @@ numReviews=#1 review;#1 reviews
dateUpdated=Updated %S
#LOCALIZATION NOTE (notification.incompatible) %1$S is the add-on name, %2$S is brand name, %3$S is application version
notification.incompatible=%1$S is incompatible with %2$S %3$S.
#LOCALIZATION NOTE (notification.unsigned, notification.unsignedAndDisabled) %1$S is the add-on name, %2$S is brand name
notification.unsignedAndDisabled=%1$S could not be verified for use in %2$S and has been disabled.
notification.unsigned=%1$S could not be verified for use in %2$S. Proceed with caution.
notification.unsigned.link=More Information
+#LOCALIZATION NOTE (notification.nonMpcDisabled) %1$S is the add-on name
+notification.nonMpcDisabled=%1$S has been disabled since it is not multiprocess compatible.
+notification.nonMpcDisabled.link=More Information
#LOCALIZATION NOTE (notification.blocked) %1$S is the add-on name
notification.blocked=%1$S has been disabled due to security or stability issues.
notification.blocked.link=More Information
#LOCALIZATION NOTE (notification.softblocked) %1$S is the add-on name
notification.softblocked=%1$S is known to cause security or stability issues.
notification.softblocked.link=More Information
#LOCALIZATION NOTE (notification.outdated) %1$S is the add-on name
notification.outdated=An important update is available for %1$S.
@@ -77,16 +80,19 @@ installFailed=Error installing
installCancelled=Install cancelled
#LOCALIZATION NOTE (details.notification.incompatible) %1$S is the add-on name, %2$S is brand name, %3$S is application version
details.notification.incompatible=%1$S is incompatible with %2$S %3$S.
#LOCALIZATION NOTE (details.notification.unsigned, details.notification.unsignedAndDisabled) %1$S is the add-on name, %2$S is brand name
details.notification.unsignedAndDisabled=%1$S could not be verified for use in %2$S and has been disabled.
details.notification.unsigned=%1$S could not be verified for use in %2$S. Proceed with caution.
details.notification.unsigned.link=More Information
+#LOCALIZATION NOTE (details.notification.nonMpcDisabled) %1$S is the add-on name
+details.notification.nonMpcDisabled=%1$S has been disabled since it is not multiprocess compatible.
+details.notification.nonMpcDisabled.link=More Information
#LOCALIZATION NOTE (details.notification.blocked) %1$S is the add-on name
details.notification.blocked=%1$S has been disabled due to security or stability issues.
details.notification.blocked.link=More Information
#LOCALIZATION NOTE (details.notification.softblocked) %1$S is the add-on name
details.notification.softblocked=%1$S is known to cause security or stability issues.
details.notification.softblocked.link=More Information
#LOCALIZATION NOTE (details.notification.outdated) %1$S is the add-on name
details.notification.outdated=An important update is available for %1$S.
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -40,16 +40,18 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Experiments",
"resource:///modules/experiments/Experiments.jsm");
XPCOMUtils.defineLazyPreferenceGetter(this, "WEBEXT_PERMISSION_PROMPTS",
"extensions.webextPermissionPrompts", false);
+XPCOMUtils.defineLazyPreferenceGetter(this, "ALLOW_NON_MPC",
+ "extensions.allow-non-mpc-extensions", true);
const PREF_DISCOVERURL = "extensions.webservice.discoverURL";
const PREF_DISCOVER_ENABLED = "extensions.getAddons.showPane";
const PREF_XPI_ENABLED = "xpinstall.enabled";
const PREF_MAXRESULTS = "extensions.getAddons.maxResults";
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
const PREF_GETADDONS_CACHE_ID_ENABLED = "extensions.%ID%.getAddons.cache.enabled";
const PREF_UI_TYPE_HIDDEN = "extensions.ui.%TYPE%.hidden";
@@ -3373,16 +3375,24 @@ var gDetailView = {
} else if (!this._addon.isCompatible && (AddonManager.checkCompatibility ||
(this._addon.blocklistState != Ci.nsIBlocklistService.STATE_SOFTBLOCKED))) {
this.node.setAttribute("notification", "warning");
document.getElementById("detail-warning").textContent = gStrings.ext.formatStringFromName(
"details.notification.incompatible",
[this._addon.name, gStrings.brandShortName, gStrings.appVersion], 3
);
document.getElementById("detail-warning-link").hidden = true;
+ } else if (this.appDisabled && !this._addon.multiprocessCompatible && !ALLOW_NON_MPC) {
+ this.node.setAttribute("notification", "error");
+ document.getElementById("detail-error").textContent = gStrings.ext.formatStringFromName(
+ "details.notification.nonMpcDisabled", [this._addon.name], 1
+ );
+ let errorLink = document.getElementById("detail-error-link");
+ errorLink.value = gStrings.ext.GetStringFromName("details.notification.nonMpcDisabled.link");
+ errorLink.href = "https://wiki.mozilla.org/Add-ons/ShimsNightly";
} else if (!isCorrectlySigned(this._addon)) {
this.node.setAttribute("notification", "warning");
document.getElementById("detail-warning").textContent = gStrings.ext.formatStringFromName(
"details.notification.unsigned", [this._addon.name, gStrings.brandShortName], 2
);
var warningLink = document.getElementById("detail-warning-link");
warningLink.value = gStrings.ext.GetStringFromName("details.notification.unsigned.link");
warningLink.href = Services.urlFormatter.formatURLPref("app.support.baseURL") + "unsigned-addons";
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -1278,16 +1278,25 @@
|| (this.mAddon.blocklistState != Ci.nsIBlocklistService.STATE_SOFTBLOCKED))) {
this.setAttribute("notification", "warning");
this._warning.textContent = gStrings.ext.formatStringFromName(
"notification.incompatible",
[this.mAddon.name, gStrings.brandShortName, gStrings.appVersion], 3
);
this._warningLink.hidden = true;
this._warningBtn.hidden = true;
+ } else if (!isUpgrade && !this.mAddon.multiprocessCompatible &&
+ !Services.prefs.getBoolPref("extensions.allow-non-mpc-extensions", true)) {
+ this.setAttribute("notification", "error");
+ this._error.textContent = gStrings.ext.formatStringFromName(
+ "notification.nonMpcDisabled", [this.mAddon.name], 1
+ );
+ this._errorLink.value = gStrings.ext.GetStringFromName("notification.nonMpcDisabled.link");
+ this._errorLink.href = "https://wiki.mozilla.org/Add-ons/ShimsNightly";
+ this._errorLink.hidden = false;
} else if (!isUpgrade && !isCorrectlySigned(this.mAddon)) {
this.setAttribute("notification", "warning");
this._warning.textContent = gStrings.ext.formatStringFromName(
"notification.unsigned", [this.mAddon.name, gStrings.brandShortName], 2
);
this._warningLink.value = gStrings.ext.GetStringFromName("notification.unsigned.link");
this._warningLink.href = Services.urlFormatter.formatURLPref("app.support.baseURL") + "unsigned-addons";
this._warningLink.hidden = false;
--- a/toolkit/mozapps/extensions/test/browser/browser.ini
+++ b/toolkit/mozapps/extensions/test/browser/browser.ini
@@ -60,16 +60,17 @@ skip-if = buildapp == 'mulet'
[browser_getmorethemes.js]
[browser_gmpProvider.js]
[browser_hotfix.js]
# Verifies the old style of signing hotfixes
skip-if = require_signing
[browser_install.js]
[browser_installssl.js]
[browser_newaddon.js]
+[browser_non_mpc.js]
[browser_searching.js]
[browser_system_addons_are_e10s.js]
[browser_task_next_test.js]
[browser_update.js]
[browser_updatessl.js]
[browser_webapi.js]
[browser_webapi_access.js]
[browser_webapi_addon_listener.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/browser/browser_non_mpc.js
@@ -0,0 +1,91 @@
+
+add_task(async function() {
+ let extensions = [
+ {
+ id: "mpc@tests.mozilla.org",
+ name: "Compatible extension",
+ multiprocessCompatible: true,
+ },
+ {
+ id: "not-mpc@tests.mozilla.org",
+ name: "Incompatible extension",
+ multiprocessCompatible: false,
+ },
+ ];
+
+ let provider = new MockProvider();
+ provider.createAddons(extensions);
+
+ let mgrWin = await open_manager(null);
+ let catUtils = new CategoryUtilities(mgrWin);
+
+ async function check(name, disabled) {
+ await catUtils.openType("extension");
+
+ let document = mgrWin.document;
+ // First find the extension entry in the extensions list.
+ let item = Array.from(document.getElementById("addon-list").childNodes)
+ .find(i => i.getAttribute("name") == name);
+
+ ok(item, `Found ${name} in extensions list`);
+ item.parentNode.ensureElementIsVisible(item);
+
+ // Check individual elements on this item.
+ let disabledPostfix = document.getAnonymousElementByAttribute(item, "class", "disabled-postfix");
+ let enableBtn = document.getAnonymousElementByAttribute(item, "anonid", "enable-btn");
+ let disableBtn = document.getAnonymousElementByAttribute(item, "anonid", "disable-btn");
+ let errorMsg = document.getAnonymousElementByAttribute(item, "anonid", "error");
+ let errorLink = document.getAnonymousElementByAttribute(item, "anonid", "error-link");
+
+ if (disabled) {
+ is_element_visible(disabledPostfix, "Disabled postfix should be visible");
+ is_element_hidden(enableBtn, "Enable button should be hidden");
+ is_element_hidden(disableBtn, "Disable button should be hidden");
+ is_element_visible(errorMsg, "Error message should be visible");
+ is_element_visible(errorLink, "Error link should be visible");
+ } else {
+ is_element_hidden(disabledPostfix, "Disabled postfix should be hidden");
+ is_element_hidden(enableBtn, "Enable button should be hidden");
+ is_element_visible(disableBtn, "Disable button should be visible");
+ is_element_hidden(errorMsg, "Error message should be hidden");
+ is_element_hidden(errorLink, "Error link should be hidden");
+ }
+
+ // Click down to the details page.
+ EventUtils.synthesizeMouseAtCenter(item, {clickCount: 2}, mgrWin);
+ await new Promise(resolve => wait_for_view_load(mgrWin, resolve));
+
+ // And check its contents.
+ enableBtn = mgrWin.document.getElementById("detail-enable-btn");
+ disableBtn = mgrWin.document.getElementById("detail-disable-btn");
+ errorMsg = mgrWin.document.getElementById("detail-error");
+
+ if (disabled) {
+ is_element_hidden(enableBtn, "Enable button should be hidden");
+ is_element_hidden(disableBtn, "Disable button should be hidden");
+ is_element_visible(errorMsg, "Error message should be visible");
+ } else {
+ is_element_hidden(enableBtn, "Enable button should be hidden");
+ is_element_visible(disableBtn, "Disable button should be visible");
+ is_element_hidden(errorMsg, "Error message should be hidden");
+ }
+ }
+
+ // Initially, both extensions should be enabled
+ await check("Compatible extension", false);
+ await check("Incompatible extension", false);
+
+ // Flip the pref, making the non-MPC extension disabled.
+ await SpecialPowers.pushPrefEnv({
+ set: [["extensions.allow-non-mpc-extensions", false]],
+ });
+ extensions[1].multiprocessCompatible = false;
+ extensions[1].appDisabled = true;
+
+ // The compatible extensions should be unaffected, the incompatible
+ // one should have the error message etc.
+ check("Compatible extension", false);
+ check("Incompatible extension", true);
+
+ await close_manager(mgrWin);
+});