Bug 1513541 - Ensure system addons are not accidentally started on start-up even if their about:config preferences are off; r=kmag
authorThomas Wisniewski <twisniewski@mozilla.com>
Fri, 18 Jan 2019 04:49:19 +0000
changeset 511491 054b7887f985c6a2b97c6cf5815f9d72fc5ba116
parent 511490 ddb55e312c8a2971091d704a52aec679c85b264d
child 511492 aa5836f97faf2535d4f579cd798aad0ba620406a
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1513541
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1513541 - Ensure system addons are not accidentally started on start-up even if their about:config preferences are off; r=kmag Ensure system addons are not accidentally started on start-up even if their about:config preferences are off. Differential Revision: https://phabricator.services.mozilla.com/D14297
toolkit/mozapps/extensions/internal/XPIDatabase.jsm
toolkit/mozapps/extensions/test/xpcshell/test_systemaddomstartupprefs.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -2364,21 +2364,16 @@ this.XPIDatabaseReconcile = {
 
     // Assume that add-ons in the system add-ons install location aren't
     // foreign and should default to enabled.
     aNewAddon.foreignInstall = isDetectedInstall && !aLocation.isSystem;
 
     // appDisabled depends on whether the add-on is a foreignInstall so update
     aNewAddon.appDisabled = !XPIDatabase.isUsableAddon(aNewAddon);
 
-    if (aLocation.isSystem) {
-      const pref = `extensions.${aId.split("@")[0]}.enabled`;
-      aNewAddon.userDisabled = !Services.prefs.getBoolPref(pref, true);
-    }
-
     if (isDetectedInstall && aNewAddon.foreignInstall) {
       // Add the installation source info for the sideloaded extension.
       aNewAddon.installTelemetryInfo = {
         source: aLocation.name,
         method: "sideload",
       };
 
       // If the add-on is a foreign install and is in a scope where add-ons
@@ -2552,16 +2547,29 @@ this.XPIDatabaseReconcile = {
    *        True if this location is part of the application bundle.
    */
   isAppBundledLocation(location) {
     return (location.name == KEY_APP_GLOBAL ||
             location.name == KEY_APP_SYSTEM_DEFAULTS);
   },
 
   /**
+   * Returns true if this install location holds system addons.
+   *
+   * @param {XPIStateLocation} location
+   *        The install location to check.
+   * @returns {boolean}
+   *        True if this location contains system add-ons.
+   */
+  isSystemAddonLocation(location) {
+    return location.name === KEY_APP_SYSTEM_DEFAULTS ||
+           location.name === KEY_APP_SYSTEM_ADDONS;
+  },
+
+  /**
    * Updates the databse metadata for an existing add-on during database
    * reconciliation.
    *
    * @param {AddonInternal} oldAddon
    *        The existing database add-on entry.
    * @param {XPIState} xpiState
    *        The XPIStates entry for this add-on.
    * @param {AddonInternal?} newAddon
@@ -2685,16 +2693,23 @@ this.XPIDatabaseReconcile = {
         let newAddon = findManifest(location, id);
         let addon = this.addMetadata(location, id, xpiState, newAddon,
                                      aOldAppVersion, aOldPlatformVersion);
         if (addon) {
           locationAddons.set(addon.id, addon);
           addonStates.set(addon, xpiState);
         }
       }
+
+      if (this.isSystemAddonLocation(location)) {
+        for (let [id, addon] of locationAddons.entries()) {
+          const pref = `extensions.${id.split("@")[0]}.enabled`;
+          addon.userDisabled = !Services.prefs.getBoolPref(pref, true);
+        }
+      }
     }
 
     // Validate the updated system add-ons
     let hideLocation;
     {
       let systemAddonLocation = XPIStates.getLocation(KEY_APP_SYSTEM_ADDONS);
       let addons = currentAddons.get(systemAddonLocation.name);
 
@@ -2805,16 +2820,20 @@ this.XPIDatabaseReconcile = {
       if (previousAddon !== currentAddon) {
         AddonManagerPrivate.addStartupChange(AddonManager.STARTUP_CHANGE_CHANGED, id);
 
         if (previousAddon.location &&
             previousAddon._sourceBundle.exists() &&
             !previousAddon._sourceBundle.equals(currentAddon._sourceBundle)) {
           promise = XPIInternal.BootstrapScope.get(previousAddon).update(
             currentAddon);
+        } else if (this.isSystemAddonLocation(currentAddon.location) &&
+                   previousAddon.version == currentAddon.version &&
+                   previousAddon.userDisabled != currentAddon.userDisabled) {
+          // A system addon change, no need for install or update events.
         } else {
           let reason = XPIInstall.newVersionReason(previousAddon.version, currentAddon.version);
           XPIInternal.BootstrapScope.get(currentAddon).install(
             reason, false, {oldVersion: previousAddon.version});
         }
       }
 
       if (isActive != wasActive) {
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_systemaddomstartupprefs.js
@@ -0,0 +1,56 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// This verifies that system addon about:config prefs
+// are honored during startup/restarts/upgrades.
+createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2");
+
+let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"], true);
+registerDirectory("XREAppFeat", distroDir);
+
+AddonTestUtils.usePrivilegedSignatures = "system";
+
+add_task(initSystemAddonDirs);
+
+let Monitor = SlightlyLessDodgyBootstrapMonitor;
+Monitor.init();
+
+add_task(async function setup() {
+  let xpi = await getSystemAddonXPI(1, "1.0");
+  await AddonTestUtils.manuallyInstall(xpi, distroDir);
+});
+
+add_task(async function systemAddonPreffedOff() {
+  const id = "system1@tests.mozilla.org";
+  Services.prefs.setBoolPref("extensions.system1.enabled", false);
+
+  await overrideBuiltIns({"system": [id]});
+
+  await promiseStartupManager();
+
+  Monitor.checkInstalled(id);
+  Monitor.checkNotStarted(id);
+
+  await promiseRestartManager();
+
+  Monitor.checkNotStarted(id);
+
+  await promiseShutdownManager(false);
+});
+
+add_task(async function systemAddonPreffedOn() {
+  const id = "system1@tests.mozilla.org";
+  Services.prefs.setBoolPref("extensions.system1.enabled", true);
+
+  await promiseStartupManager("2.0");
+
+  Monitor.checkInstalled(id);
+  Monitor.checkStarted(id);
+
+  await promiseRestartManager();
+
+  Monitor.checkStarted(id);
+
+  await promiseShutdownManager();
+});
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -225,16 +225,18 @@ head = head_addons.js head_system_addons
 head = head_addons.js head_system_addons.js
 [test_temporary.js]
 skip-if = os == "win" # Bug 1469904
 tags = webextensions
 [test_theme_update.js]
 [test_trash_directory.js]
 skip-if = os != "win"
 [test_types.js]
+[test_systemaddomstartupprefs.js]
+head = head_addons.js head_system_addons.js
 [test_undouninstall.js]
 skip-if = os == "win" # Bug 1358846
 [test_update.js]
 # Bug 676992: test consistently hangs on Android; bug 1330227 - linux
 skip-if = os == "android"
 [test_updateCancel.js]
 [test_update_compatmode.js]
 head = head_addons.js head_compat.js