Bug 1404584 Part 1: Use extensionId in ExtensionSettingsStore and ExtensionPreferencesManager methods, r?aswan draft
authorAndrew Swan <aswan@mozilla.com>
Tue, 24 Oct 2017 20:18:03 -0700
changeset 699247 4da5e63a544ca575de3dc35d750109a419916973
parent 699096 a3f183201f7f183c263d554bfb15fbf0b0ed2ea4
child 699248 f53d21b1089e57c0e5ba42c60c9d13a06a2c6d36
push id89511
push userbmo:bob.silverberg@gmail.com
push dateThu, 16 Nov 2017 21:45:06 +0000
reviewersaswan
bugs1404584
milestone59.0a1
Bug 1404584 Part 1: Use extensionId in ExtensionSettingsStore and ExtensionPreferencesManager methods, r?aswan This code changes all of the functions in the ESS and the EPM to accept an extensionId rather than an extension object, which is required for responding to the new onUpdate event. MozReview-Commit-ID: FwMVa0fShGj
browser/components/extensions/ext-chrome-settings-overrides.js
browser/components/extensions/ext-url-overrides.js
toolkit/components/extensions/ExtensionPreferencesManager.jsm
toolkit/components/extensions/ExtensionSettingsStore.jsm
toolkit/components/extensions/ext-browserSettings.js
toolkit/components/extensions/ext-contextualIdentities.js
toolkit/components/extensions/ext-privacy.js
toolkit/components/extensions/test/xpcshell/test_ext_extensionPreferencesManager.js
toolkit/components/extensions/test/xpcshell/test_ext_extensionSettingsStore.js
--- a/browser/components/extensions/ext-chrome-settings-overrides.js
+++ b/browser/components/extensions/ext-chrome-settings-overrides.js
@@ -40,20 +40,20 @@ this.chrome_settings_overrides = class e
     if (!item) {
       return;
     }
     if (Services.search.currentEngine.name != item.value &&
         Services.search.currentEngine.name != item.initialValue) {
       // The current engine is not the same as the value that the ExtensionSettingsStore has.
       // This means that the user changed the engine, so we shouldn't control it anymore.
       // Do nothing and remove our entry from the ExtensionSettingsStore.
-      ExtensionSettingsStore.removeSetting(extension, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME);
+      ExtensionSettingsStore.removeSetting(extension.id, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME);
       return;
     }
-    item = ExtensionSettingsStore[action](extension, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME);
+    item = ExtensionSettingsStore[action](extension.id, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME);
     if (item) {
       try {
         let engine = Services.search.getEngineByName(item.value || item.initialValue);
         if (engine) {
           Services.search.currentEngine = engine;
         }
       } catch (e) {
         Components.utils.reportError(e);
@@ -62,17 +62,17 @@ this.chrome_settings_overrides = class e
   }
 
   async onManifestEntry(entryName) {
     let {extension} = this;
     let {manifest} = extension;
 
     await ExtensionSettingsStore.initialize();
     if (manifest.chrome_settings_overrides.homepage) {
-      ExtensionPreferencesManager.setSetting(extension, "homepage_override",
+      ExtensionPreferencesManager.setSetting(extension.id, "homepage_override",
                                              manifest.chrome_settings_overrides.homepage);
     }
     if (manifest.chrome_settings_overrides.search_provider) {
       await searchInitialized();
       extension.callOnClose({
         close: () => {
           if (extension.shutdownReason == "ADDON_DISABLE" ||
               extension.shutdownReason == "ADDON_UNINSTALL") {
@@ -137,29 +137,29 @@ this.chrome_settings_overrides = class e
               return;
             }
           }
         }
         // Needs to be called every time to handle reenabling, but
         // only sets default for install or enable.
         await this.setDefault(engineName);
       } else if (ExtensionSettingsStore.hasSetting(
-                extension, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME)) {
+                extension.id, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME)) {
         // is_default has been removed, but we still have a setting. Remove it.
         // This won't cover the case where the entire search_provider is removed.
         this.processDefaultSearchSetting("removeSetting");
       }
     }
   }
 
   async setDefault(engineName) {
     let {extension} = this;
     if (extension.startupReason === "ADDON_INSTALL") {
       let item = await ExtensionSettingsStore.addSetting(
-        extension, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME, engineName, () => {
+        extension.id, DEFAULT_SEARCH_STORE_TYPE, DEFAULT_SEARCH_SETTING_NAME, engineName, () => {
           return Services.search.currentEngine.name;
         });
       Services.search.currentEngine = Services.search.getEngineByName(item.value);
     } else if (extension.startupReason === "ADDON_ENABLE") {
       this.processDefaultSearchSetting("enable");
     }
   }
 
--- a/browser/components/extensions/ext-url-overrides.js
+++ b/browser/components/extensions/ext-url-overrides.js
@@ -12,17 +12,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "nsIAboutNewTabService");
 
 const STORE_TYPE = "url_overrides";
 const NEW_TAB_SETTING_NAME = "newTabURL";
 
 this.urlOverrides = class extends ExtensionAPI {
   processNewTabSetting(action) {
     let {extension} = this;
-    let item = ExtensionSettingsStore[action](extension, STORE_TYPE, NEW_TAB_SETTING_NAME);
+    let item = ExtensionSettingsStore[action](extension.id, STORE_TYPE, NEW_TAB_SETTING_NAME);
     if (item) {
       aboutNewTabService.newTabURL = item.value || item.initialValue;
     }
   }
 
   async onManifestEntry(entryName) {
     let {extension} = this;
     let {manifest} = extension;
@@ -48,24 +48,24 @@ this.urlOverrides = class extends Extens
               break;
           }
         },
       });
 
       let url = extension.baseURI.resolve(manifest.chrome_url_overrides.newtab);
 
       let item = await ExtensionSettingsStore.addSetting(
-        extension, STORE_TYPE, NEW_TAB_SETTING_NAME, url,
+        extension.id, STORE_TYPE, NEW_TAB_SETTING_NAME, url,
         () => aboutNewTabService.newTabURL);
 
       // If the extension was just re-enabled, change the setting to enabled.
       // This is required because addSetting above is used for both add and update.
       if (["ADDON_ENABLE", "ADDON_UPGRADE", "ADDON_DOWNGRADE"]
           .includes(extension.startupReason)) {
-        item = ExtensionSettingsStore.enable(extension, STORE_TYPE, NEW_TAB_SETTING_NAME);
+        item = ExtensionSettingsStore.enable(extension.id, STORE_TYPE, NEW_TAB_SETTING_NAME);
       }
 
       // Set the newTabURL to the current value of the setting.
       if (item) {
         aboutNewTabService.newTabURL = item.value || item.initialValue;
       }
     }
   }
--- a/toolkit/components/extensions/ExtensionPreferencesManager.jsm
+++ b/toolkit/components/extensions/ExtensionPreferencesManager.jsm
@@ -45,28 +45,28 @@ const ADDON_REPLACE_REASONS = new Set([
 Management.on("shutdown", (type, extension) => {
   switch (extension.shutdownReason) {
     case "ADDON_DISABLE":
     case "ADDON_DOWNGRADE":
     case "ADDON_UPGRADE":
       if (ADDON_REPLACE_REASONS.has(extension.shutdownReason)) {
         Services.obs.notifyObservers(null, "web-extension-preferences-replacing");
       }
-      this.ExtensionPreferencesManager.disableAll(extension);
+      this.ExtensionPreferencesManager.disableAll(extension.id);
       break;
 
     case "ADDON_UNINSTALL":
-      this.ExtensionPreferencesManager.removeAll(extension);
+      this.ExtensionPreferencesManager.removeAll(extension.id);
       break;
   }
 });
 
 Management.on("startup", async (type, extension) => {
   if (["ADDON_ENABLE", "ADDON_UPGRADE", "ADDON_DOWNGRADE"].includes(extension.startupReason)) {
-    const enablePromise = this.ExtensionPreferencesManager.enableAll(extension);
+    const enablePromise = this.ExtensionPreferencesManager.enableAll(extension.id);
     if (ADDON_REPLACE_REASONS.has(extension.startupReason)) {
       await enablePromise;
       Services.obs.notifyObservers(null, "web-extension-preferences-replaced");
     }
   }
 });
 /* eslint-enable mozilla/balanced-listeners */
 
@@ -119,32 +119,32 @@ function setPrefs(setting, item) {
  * If the change to the setting causes a different extension to gain
  * control of the pref (or removes all extensions with control over the pref)
  * then the prefs should be updated, otherwise they should not be.
  * In addition, if the current value of any of the prefs does not
  * match what we expect the value to be (which could be the result of a
  * user manually changing the pref value), then we do not change any
  * of the prefs.
  *
- * @param {Extension} extension
- *        The extension for which a setting is being modified.
+ * @param {string} id
+ *        The id of the extension for which a setting is being modified.
  * @param {string} name
  *        The name of the setting being processed.
  * @param {string} action
  *        The action that is being performed. Will be one of disable, enable
  *        or removeSetting.
 
  * @returns {Promise}
  *          Resolves to true if preferences were set as a result and to false
  *          if preferences were not set.
 */
-async function processSetting(extension, name, action) {
+async function processSetting(id, name, action) {
   await ExtensionSettingsStore.initialize();
   let expectedItem = ExtensionSettingsStore.getSetting(STORE_TYPE, name);
-  let item = ExtensionSettingsStore[action](extension, STORE_TYPE, name);
+  let item = ExtensionSettingsStore[action](id, STORE_TYPE, name);
   if (item) {
     let setting = settingsMap.get(name);
     let expectedPrefs = expectedItem.initialValue
       || setting.setCallback(expectedItem.value);
     if (Object.keys(expectedPrefs).some(
         pref => expectedPrefs[pref] && Preferences.get(pref) != expectedPrefs[pref])) {
       return false;
     }
@@ -180,136 +180,136 @@ this.ExtensionPreferencesManager = {
   getDefaultValue(prefName) {
     return defaultPreferences.get(prefName);
   },
 
   /**
    * Indicates that an extension would like to change the value of a previously
    * defined setting.
    *
-   * @param {Extension} extension
-   *        The extension for which a setting is being set.
+   * @param {string} id
+   *        The id of the extension for which a setting is being set.
    * @param {string} name
    *        The unique id of the setting.
    * @param {any} value
    *        The value to be stored in the settings store for this
    *        group of preferences.
    *
    * @returns {Promise}
    *          Resolves to true if the preferences were changed and to false if
    *          the preferences were not changed.
    */
-  async setSetting(extension, name, value) {
+  async setSetting(id, name, value) {
     let setting = settingsMap.get(name);
     await ExtensionSettingsStore.initialize();
     let item = await ExtensionSettingsStore.addSetting(
-      extension, STORE_TYPE, name, value, initialValueCallback.bind(setting));
+      id, STORE_TYPE, name, value, initialValueCallback.bind(setting));
     if (item) {
       setPrefs(setting, item);
       return true;
     }
     return false;
   },
 
   /**
    * Indicates that this extension wants to temporarily cede control over the
    * given setting.
    *
-   * @param {Extension} extension
-   *        The extension for which a preference setting is being removed.
+   * @param {string} id
+   *        The id of the extension for which a preference setting is being disabled.
    * @param {string} name
    *        The unique id of the setting.
    *
    * @returns {Promise}
    *          Resolves to true if the preferences were changed and to false if
    *          the preferences were not changed.
    */
-  disableSetting(extension, name) {
-    return processSetting(extension, name, "disable");
+  disableSetting(id, name) {
+    return processSetting(id, name, "disable");
   },
 
   /**
    * Enable a setting that has been disabled.
    *
-   * @param {Extension} extension
-   *        The extension for which a setting is being enabled.
+   * @param {string} id
+   *        The id of the extension for which a setting is being enabled.
    * @param {string} name
    *        The unique id of the setting.
    *
    * @returns {Promise}
    *          Resolves to true if the preferences were changed and to false if
    *          the preferences were not changed.
    */
-  enableSetting(extension, name) {
-    return processSetting(extension, name, "enable");
+  enableSetting(id, name) {
+    return processSetting(id, name, "enable");
   },
 
   /**
    * Indicates that this extension no longer wants to set the given setting.
    *
-   * @param {Extension} extension
-   *        The extension for which a preference setting is being removed.
+   * @param {string} id
+   *        The id of the extension for which a preference setting is being removed.
    * @param {string} name
    *        The unique id of the setting.
    *
    * @returns {Promise}
    *          Resolves to true if the preferences were changed and to false if
    *          the preferences were not changed.
    */
-  removeSetting(extension, name) {
-    return processSetting(extension, name, "removeSetting");
+  removeSetting(id, name) {
+    return processSetting(id, name, "removeSetting");
   },
 
   /**
    * Disables all previously set settings for an extension. This can be called when
    * an extension is being disabled, for example.
    *
-   * @param {Extension} extension
-   *        The extension for which all settings are being unset.
+   * @param {string} id
+   *        The id of the extension for which all settings are being unset.
    */
-  async disableAll(extension) {
+  async disableAll(id) {
     await ExtensionSettingsStore.initialize();
-    let settings = ExtensionSettingsStore.getAllForExtension(extension, STORE_TYPE);
+    let settings = ExtensionSettingsStore.getAllForExtension(id, STORE_TYPE);
     let disablePromises = [];
     for (let name of settings) {
-      disablePromises.push(this.disableSetting(extension, name));
+      disablePromises.push(this.disableSetting(id, name));
     }
     await Promise.all(disablePromises);
   },
 
   /**
    * Enables all disabled settings for an extension. This can be called when
    * an extension has finsihed updating or is being re-enabled, for example.
    *
-   * @param {Extension} extension
-   *        The extension for which all settings are being enabled.
+   * @param {string} id
+   *        The id of the extension for which all settings are being enabled.
    */
-  async enableAll(extension) {
+  async enableAll(id) {
     await ExtensionSettingsStore.initialize();
-    let settings = ExtensionSettingsStore.getAllForExtension(extension, STORE_TYPE);
+    let settings = ExtensionSettingsStore.getAllForExtension(id, STORE_TYPE);
     let enablePromises = [];
     for (let name of settings) {
-      enablePromises.push(this.enableSetting(extension, name));
+      enablePromises.push(this.enableSetting(id, name));
     }
     await Promise.all(enablePromises);
   },
 
   /**
    * Removes all previously set settings for an extension. This can be called when
    * an extension is being uninstalled, for example.
    *
-   * @param {Extension} extension
-   *        The extension for which all settings are being unset.
+   * @param {string} id
+   *        The id of the extension for which all settings are being unset.
    */
-  async removeAll(extension) {
+  async removeAll(id) {
     await ExtensionSettingsStore.initialize();
-    let settings = ExtensionSettingsStore.getAllForExtension(extension, STORE_TYPE);
+    let settings = ExtensionSettingsStore.getAllForExtension(id, STORE_TYPE);
     let removePromises = [];
     for (let name of settings) {
-      removePromises.push(this.removeSetting(extension, name));
+      removePromises.push(this.removeSetting(id, name));
     }
     await Promise.all(removePromises);
   },
 
   /**
    * Return the currently active value for a setting.
    *
    * @param {string} name
@@ -322,37 +322,37 @@ this.ExtensionPreferencesManager = {
     return ExtensionSettingsStore.getSetting(STORE_TYPE, name);
   },
 
   /**
    * Return the levelOfControl for a setting / extension combo.
    * This queries the levelOfControl from the ExtensionSettingsStore and also
    * takes into account whether any of the setting's preferences are locked.
    *
-   * @param {Extension} extension
-   *        The extension for which levelOfControl is being requested.
+   * @param {string} id
+   *        The id of the extension for which levelOfControl is being requested.
    * @param {string} name
    *        The unique id of the setting.
    * @param {string} storeType
    *        The name of the store in ExtensionSettingsStore.
    *        Defaults to STORE_TYPE.
    *
    * @returns {Promise}
    *          Resolves to the level of control of the extension over the setting.
    */
-  async getLevelOfControl(extension, name, storeType = STORE_TYPE) {
+  async getLevelOfControl(id, name, storeType = STORE_TYPE) {
     // This could be called for a setting that isn't defined to the PreferencesManager,
     // in which case we simply defer to the SettingsStore.
     if (storeType === STORE_TYPE) {
       let setting = settingsMap.get(name);
       if (!setting) {
         return "not_controllable";
       }
       for (let prefName of setting.prefNames) {
         if (Preferences.locked(prefName)) {
           return "not_controllable";
         }
       }
     }
     await ExtensionSettingsStore.initialize();
-    return ExtensionSettingsStore.getLevelOfControl(extension, storeType, name);
+    return ExtensionSettingsStore.getLevelOfControl(id, storeType, name);
   },
 };
--- a/toolkit/components/extensions/ExtensionSettingsStore.jsm
+++ b/toolkit/components/extensions/ExtensionSettingsStore.jsm
@@ -141,45 +141,44 @@ function precedenceComparator(a, b) {
   }
   return b.installDate - a.installDate;
 }
 
 /**
  * Helper method that alters a setting, either by changing its enabled status
  * or by removing it.
  *
- * @param {Extension} extension
- *        The extension for which a setting is being removed/disabled.
+ * @param {string} id
+ *        The id of the extension for which a setting is being removed/disabled.
  * @param {string} type
  *        The type of setting to be altered.
  * @param {string} key
  *        A string that uniquely identifies the setting.
  * @param {string} action
  *        The action to perform on the setting.
  *        Will be one of remove|enable|disable.
  *
  * @returns {object | null}
  *          Either an object with properties for key and value, which
  *          corresponds to the current top precedent setting, or null if
  *          the current top precedent setting has not changed.
  */
-function alterSetting(extension, type, key, action) {
+function alterSetting(id, type, key, action) {
   let returnItem;
   ensureType(type);
 
   let keyInfo = _store.data[type][key];
   if (!keyInfo) {
     if (action === "remove") {
       return null;
     }
     throw new Error(
       `Cannot alter the setting for ${type}:${key} as it does not exist.`);
   }
 
-  let id = extension.id;
   let foundIndex = keyInfo.precedenceList.findIndex(item => item.id == id);
 
   if (foundIndex === -1) {
     if (action === "remove") {
       return null;
     }
     throw new Error(
       `Cannot alter the setting for ${type}:${key} as it does not exist.`);
@@ -230,18 +229,18 @@ this.ExtensionSettingsStore = {
   initialize() {
     return initialize();
   },
 
   /**
    * Adds a setting to the store, possibly returning the current top precedent
    * setting.
    *
-   * @param {Extension} extension
-   *        The extension for which a setting is being added.
+   * @param {string} id
+   *        The id of the extension for which a setting is being added.
    * @param {string} type
    *        The type of setting to be stored.
    * @param {string} key
    *        A string that uniquely identifies the setting.
    * @param {string} value
    *        The value to be stored in the setting.
    * @param {function} initialValueCallback
    *        An function to be called to determine the initial value for the
@@ -252,22 +251,21 @@ this.ExtensionSettingsStore = {
    *        the value of the key argument.
    *
    * @returns {object | null} Either an object with properties for key and
    *                          value, which corresponds to the item that was
    *                          just added, or null if the item that was just
    *                          added does not need to be set because it is not
    *                          at the top of the precedence list.
    */
-  async addSetting(extension, type, key, value, initialValueCallback, callbackArgument = key) {
+  async addSetting(id, type, key, value, initialValueCallback, callbackArgument = key) {
     if (typeof initialValueCallback != "function") {
       throw new Error("initialValueCallback must be a function.");
     }
 
-    let id = extension.id;
     ensureType(type);
 
     if (!_store.data[type][key]) {
       // The setting for this key does not exist. Set the initial value.
       let initialValue = await initialValueCallback(callbackArgument);
       _store.data[type][key] = {
         initialValue,
         precedenceList: [],
@@ -297,70 +295,70 @@ this.ExtensionSettingsStore = {
     }
     return null;
   },
 
   /**
    * Removes a setting from the store, possibly returning the current top
    * precedent setting.
    *
-   * @param {Extension} extension
-   *        The extension for which a setting is being removed.
+   * @param {string} id
+   *        The id of the extension for which a setting is being removed.
    * @param {string} type
    *        The type of setting to be removed.
    * @param {string} key
    *        A string that uniquely identifies the setting.
    *
    * @returns {object | null}
    *          Either an object with properties for key and value, which
    *          corresponds to the current top precedent setting, or null if
    *          the current top precedent setting has not changed.
    */
-  removeSetting(extension, type, key) {
-    return alterSetting(extension, type, key, "remove");
+  removeSetting(id, type, key) {
+    return alterSetting(id, type, key, "remove");
   },
 
   /**
    * Enables a setting in the store, possibly returning the current top
    * precedent setting.
    *
-   * @param {Extension} extension
-   *        The extension for which a setting is being enabled.
+   * @param {string} id
+   *        The id of the extension for which a setting is being enabled.
    * @param {string} type
    *        The type of setting to be enabled.
    * @param {string} key
    *        A string that uniquely identifies the setting.
    *
    * @returns {object | null}
    *          Either an object with properties for key and value, which
    *          corresponds to the current top precedent setting, or null if
    *          the current top precedent setting has not changed.
    */
-  enable(extension, type, key) {
-    return alterSetting(extension, type, key, "enable");
+  enable(id, type, key) {
+    return alterSetting(id, type, key, "enable");
   },
 
   /**
    * Disables a setting in the store, possibly returning the current top
    * precedent setting.
    *
-   * @param {Extension} extension
-   *        The extension for which a setting is being disabled.
+   * @param {string} id
+   *        The id of the extension for which a setting is being disabled.
    * @param {string} type
    *        The type of setting to be disabled.
    * @param {string} key
    *        A string that uniquely identifies the setting.
    *
    * @returns {object | null}
    *          Either an object with properties for key and value, which
    *          corresponds to the current top precedent setting, or null if
    *          the current top precedent setting has not changed.
    */
-  disable(extension, type, key) {
-    return alterSetting(extension, type, key, "disable");
+  disable(id, type, key) {
+    return alterSetting(id, type, key, "disable");
   },
 
   /**
    * Mark a setting as being controlled by a user's choice. This will disable all of
    * the extension defined values for the extension.
    *
    * @param {string} type The type of the setting.
    * @param {string} key The key of the setting.
@@ -377,28 +375,31 @@ this.ExtensionSettingsStore = {
     }
 
     _store.saveSoon();
   },
 
   /**
    * Retrieves all settings from the store for a given extension.
    *
-   * @param {Extension} extension The extension for which a settings are being retrieved.
-   * @param {string} type The type of setting to be returned.
+   * @param {string} id
+   *        The id of the extension for which a settings are being retrieved.
+   * @param {string} type
+   *        The type of setting to be returned.
    *
-   * @returns {array} A list of settings which have been stored for the extension.
+   * @returns {array}
+   *          A list of settings which have been stored for the extension.
    */
-  getAllForExtension(extension, type) {
+  getAllForExtension(id, type) {
     ensureType(type);
 
     let keysObj = _store.data[type];
     let items = [];
     for (let key in keysObj) {
-      if (keysObj[key].precedenceList.find(item => item.id == extension.id)) {
+      if (keysObj[key].precedenceList.find(item => item.id == id)) {
         items.push(key);
       }
     }
     return items;
   },
 
   /**
    * Retrieves a setting from the store, returning the current top precedent
@@ -412,58 +413,57 @@ this.ExtensionSettingsStore = {
   getSetting(type, key) {
     return getTopItem(type, key);
   },
 
   /**
    * Returns whether an extension currently has a stored setting for a given
    * key.
    *
-   * @param {Extension} extension The extension which is being checked.
+   * @param {string} id The id of the extension which is being checked.
    * @param {string} type The type of setting to be checked.
    * @param {string} key A string that uniquely identifies the setting.
    *
    * @returns {boolean} Whether the extension currently has a stored setting.
    */
-  hasSetting(extension, type, key) {
-    return this.getAllForExtension(extension, type).includes(key);
+  hasSetting(id, type, key) {
+    return this.getAllForExtension(id, type).includes(key);
   },
 
   /**
    * Return the levelOfControl for a key / extension combo.
    * levelOfControl is required by Google's ChromeSetting prototype which
    * in turn is used by the privacy API among others.
    *
    * It informs a caller of the state of a setting with respect to the current
    * extension, and can be one of the following values:
    *
    * controlled_by_other_extensions: controlled by extensions with higher precedence
    * controllable_by_this_extension: can be controlled by this extension
    * controlled_by_this_extension: controlled by this extension
    *
-   * @param {Extension} extension
-   *        The extension for which levelOfControl is being requested.
+   * @param {string} id
+   *        The id of the extension for which levelOfControl is being requested.
    * @param {string} type
    *        The type of setting to be returned. For example `pref`.
    * @param {string} key
    *        A string that uniquely identifies the setting, for example, a
    *        preference name.
    *
    * @returns {string}
    *          The level of control of the extension over the key.
    */
-  async getLevelOfControl(extension, type, key) {
+  async getLevelOfControl(id, type, key) {
     ensureType(type);
 
     let keyInfo = _store.data[type][key];
     if (!keyInfo || !keyInfo.precedenceList.length) {
       return "controllable_by_this_extension";
     }
 
-    let id = extension.id;
     let enabledItems = keyInfo.precedenceList.filter(item => item.enabled);
     if (!enabledItems.length) {
       return "controllable_by_this_extension";
     }
 
     let topItem = enabledItems[0];
     if (topItem.id == id) {
       return "controlled_by_this_extension";
--- a/toolkit/components/extensions/ext-browserSettings.js
+++ b/toolkit/components/extensions/ext-browserSettings.js
@@ -1,14 +1,12 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
-XPCOMUtils.defineLazyModuleGetter(this, "ExtensionSettingsStore",
-                                  "resource://gre/modules/ExtensionSettingsStore.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 Cu.import("resource://gre/modules/ExtensionPreferencesManager.jsm");
@@ -22,29 +20,29 @@ const PERM_DENY_ACTION = Services.perms.
 
 const getSettingsAPI = (extension, name, callback, storeType, readOnly = false) => {
   return {
     async get(details) {
       return {
         levelOfControl: details.incognito ?
           "not_controllable" :
           await ExtensionPreferencesManager.getLevelOfControl(
-            extension, name, storeType),
+            extension.id, name, storeType),
         value: await callback(),
       };
     },
     set(details) {
       if (!readOnly) {
         return ExtensionPreferencesManager.setSetting(
-          extension, name, details.value);
+          extension.id, name, details.value);
       }
     },
     clear(details) {
       if (!readOnly) {
-        return ExtensionPreferencesManager.removeSetting(extension, name);
+        return ExtensionPreferencesManager.removeSetting(extension.id, name);
       }
     },
   };
 };
 
 // Add settings objects for supported APIs to the preferences manager.
 ExtensionPreferencesManager.addSetting("allowPopupsForUserEvents", {
   prefNames: [
--- a/toolkit/components/extensions/ext-contextualIdentities.js
+++ b/toolkit/components/extensions/ext-contextualIdentities.js
@@ -123,17 +123,17 @@ ExtensionPreferencesManager.addSetting(C
   },
 });
 
 this.contextualIdentities = class extends ExtensionAPI {
   onStartup() {
     let {extension} = this;
 
     if (extension.hasPermission("contextualIdentities")) {
-      ExtensionPreferencesManager.setSetting(extension, CONTAINERS_ENABLED_SETTING_NAME, extension.id);
+      ExtensionPreferencesManager.setSetting(extension.id, CONTAINERS_ENABLED_SETTING_NAME, extension.id);
     }
   }
 
   getAPI(context) {
     let self = {
       contextualIdentities: {
         async get(cookieStoreId) {
           checkAPIEnabled();
--- a/toolkit/components/extensions/ext-privacy.js
+++ b/toolkit/components/extensions/ext-privacy.js
@@ -19,29 +19,29 @@ const checkScope = scope => {
 
 const getPrivacyAPI = (extension, name, callback) => {
   return {
     async get(details) {
       return {
         levelOfControl: details.incognito ?
           "not_controllable" :
           await ExtensionPreferencesManager.getLevelOfControl(
-            extension, name),
+            extension.id, name),
         value: await callback(),
       };
     },
     set(details) {
       checkScope(details.scope);
       return ExtensionPreferencesManager.setSetting(
-        extension, name, details.value);
+        extension.id, name, details.value);
     },
     clear(details) {
       checkScope(details.scope);
       return ExtensionPreferencesManager.removeSetting(
-        extension, name);
+        extension.id, name);
     },
   };
 };
 
 // Add settings objects for supported APIs to the preferences manager.
 ExtensionPreferencesManager.addSetting("network.networkPredictionEnabled", {
   prefNames: [
     "network.predictor.enabled",
--- a/toolkit/components/extensions/test/xpcshell/test_ext_extensionPreferencesManager.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_extensionPreferencesManager.js
@@ -99,135 +99,135 @@ add_task(async function test_preference_
   // Create an array actual Extension objects which correspond to the
   // test framework extension wrappers.
   let extensions = testExtensions.map(extension => extension.extension);
 
   for (let setting in SETTINGS) {
     let settingObj = SETTINGS[setting];
     let newValue1 = "newValue1";
     let levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
-      extensions[1], setting);
+      extensions[1].id, setting);
     equal(levelOfControl, "controllable_by_this_extension",
       "getLevelOfControl returns correct levelOfControl with no settings set.");
 
     let prefsChanged = await ExtensionPreferencesManager.setSetting(
-      extensions[1], setting, newValue1);
+      extensions[1].id, setting, newValue1);
     ok(prefsChanged, "setSetting returns true when the pref(s) have been set.");
     checkPrefs(settingObj, newValue1,
       "setSetting sets the prefs for the first extension.");
-    levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(extensions[1], setting);
+    levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(extensions[1].id, setting);
     equal(
       levelOfControl,
       "controlled_by_this_extension",
       "getLevelOfControl returns correct levelOfControl when a pref has been set.");
 
     let checkSetting = await ExtensionPreferencesManager.getSetting(setting);
     equal(checkSetting.value, newValue1, "getSetting returns the expected value.");
 
     let newValue2 = "newValue2";
-    prefsChanged = await ExtensionPreferencesManager.setSetting(extensions[0], setting, newValue2);
+    prefsChanged = await ExtensionPreferencesManager.setSetting(extensions[0].id, setting, newValue2);
     ok(!prefsChanged, "setSetting returns false when the pref(s) have not been set.");
     checkPrefs(settingObj, newValue1,
       "setSetting does not set the pref(s) for an earlier extension.");
 
-    prefsChanged = await ExtensionPreferencesManager.disableSetting(extensions[0], setting);
+    prefsChanged = await ExtensionPreferencesManager.disableSetting(extensions[0].id, setting);
     ok(!prefsChanged, "disableSetting returns false when the pref(s) have not been set.");
     checkPrefs(settingObj, newValue1,
       "disableSetting does not change the pref(s) for the non-top extension.");
 
-    prefsChanged = await ExtensionPreferencesManager.enableSetting(extensions[0], setting);
+    prefsChanged = await ExtensionPreferencesManager.enableSetting(extensions[0].id, setting);
     ok(!prefsChanged, "enableSetting returns false when the pref(s) have not been set.");
     checkPrefs(settingObj, newValue1,
       "enableSetting does not change the pref(s) for the non-top extension.");
 
-    prefsChanged = await ExtensionPreferencesManager.removeSetting(extensions[0], setting);
+    prefsChanged = await ExtensionPreferencesManager.removeSetting(extensions[0].id, setting);
     ok(!prefsChanged, "removeSetting returns false when the pref(s) have not been set.");
     checkPrefs(settingObj, newValue1,
       "removeSetting does not change the pref(s) for the non-top extension.");
 
-    prefsChanged = await ExtensionPreferencesManager.setSetting(extensions[0], setting, newValue2);
+    prefsChanged = await ExtensionPreferencesManager.setSetting(extensions[0].id, setting, newValue2);
     ok(!prefsChanged, "setSetting returns false when the pref(s) have not been set.");
     checkPrefs(settingObj, newValue1,
       "setSetting does not set the pref(s) for an earlier extension.");
 
-    prefsChanged = await ExtensionPreferencesManager.disableSetting(extensions[1], setting);
+    prefsChanged = await ExtensionPreferencesManager.disableSetting(extensions[1].id, setting);
     ok(prefsChanged, "disableSetting returns true when the pref(s) have been set.");
     checkPrefs(settingObj, newValue2,
       "disableSetting sets the pref(s) to the next value when disabling the top extension.");
 
-    prefsChanged = await ExtensionPreferencesManager.enableSetting(extensions[1], setting);
+    prefsChanged = await ExtensionPreferencesManager.enableSetting(extensions[1].id, setting);
     ok(prefsChanged, "enableSetting returns true when the pref(s) have been set.");
     checkPrefs(settingObj, newValue1,
       "enableSetting sets the pref(s) to the previous value(s).");
 
-    prefsChanged = await ExtensionPreferencesManager.removeSetting(extensions[1], setting);
+    prefsChanged = await ExtensionPreferencesManager.removeSetting(extensions[1].id, setting);
     ok(prefsChanged, "removeSetting returns true when the pref(s) have been set.");
     checkPrefs(settingObj, newValue2,
       "removeSetting sets the pref(s) to the next value when removing the top extension.");
 
-    prefsChanged = await ExtensionPreferencesManager.removeSetting(extensions[0], setting);
+    prefsChanged = await ExtensionPreferencesManager.removeSetting(extensions[0].id, setting);
     ok(prefsChanged, "removeSetting returns true when the pref(s) have been set.");
     for (let i = 0; i < settingObj.prefNames.length; i++) {
       equal(Preferences.get(settingObj.prefNames[i]), settingObj.initalValues[i],
         "removeSetting sets the pref(s) to the initial value(s) when removing the last extension.");
     }
 
     checkSetting = await ExtensionPreferencesManager.getSetting(setting);
     equal(checkSetting, null, "getSetting returns null when nothing has been set.");
   }
 
   // Tests for unsetAll.
   let newValue3 = "newValue3";
   for (let setting in SETTINGS) {
     let settingObj = SETTINGS[setting];
-    await ExtensionPreferencesManager.setSetting(extensions[0], setting, newValue3);
+    await ExtensionPreferencesManager.setSetting(extensions[0].id, setting, newValue3);
     checkPrefs(settingObj, newValue3, "setSetting set the pref.");
   }
 
-  let setSettings = await ExtensionSettingsStore.getAllForExtension(extensions[0], STORE_TYPE);
+  let setSettings = await ExtensionSettingsStore.getAllForExtension(extensions[0].id, STORE_TYPE);
   deepEqual(setSettings, Object.keys(SETTINGS), "Expected settings were set for extension.");
-  await ExtensionPreferencesManager.disableAll(extensions[0]);
+  await ExtensionPreferencesManager.disableAll(extensions[0].id);
 
   for (let setting in SETTINGS) {
     let settingObj = SETTINGS[setting];
     for (let i = 0; i < settingObj.prefNames.length; i++) {
       equal(Preferences.get(settingObj.prefNames[i]), settingObj.initalValues[i],
         "disableAll unset the pref.");
     }
   }
 
-  setSettings = await ExtensionSettingsStore.getAllForExtension(extensions[0], STORE_TYPE);
+  setSettings = await ExtensionSettingsStore.getAllForExtension(extensions[0].id, STORE_TYPE);
   deepEqual(setSettings, Object.keys(SETTINGS), "disableAll retains the settings.");
 
-  await ExtensionPreferencesManager.enableAll(extensions[0]);
+  await ExtensionPreferencesManager.enableAll(extensions[0].id);
   for (let setting in SETTINGS) {
     let settingObj = SETTINGS[setting];
     checkPrefs(settingObj, newValue3, "enableAll re-set the pref.");
   }
 
-  await ExtensionPreferencesManager.removeAll(extensions[0]);
+  await ExtensionPreferencesManager.removeAll(extensions[0].id);
 
   for (let setting in SETTINGS) {
     let settingObj = SETTINGS[setting];
     for (let i = 0; i < settingObj.prefNames.length; i++) {
       equal(Preferences.get(settingObj.prefNames[i]), settingObj.initalValues[i],
         "removeAll unset the pref.");
     }
   }
 
-  setSettings = await ExtensionSettingsStore.getAllForExtension(extensions[0], STORE_TYPE);
+  setSettings = await ExtensionSettingsStore.getAllForExtension(extensions[0].id, STORE_TYPE);
   deepEqual(setSettings, [], "removeAll removed all settings.");
 
   // Tests for preventing automatic changes to manually edited prefs.
   for (let setting in SETTINGS) {
     let apiValue = "newValue";
     let manualValue = "something different";
     let settingObj = SETTINGS[setting];
     let extension = extensions[1];
-    await ExtensionPreferencesManager.setSetting(extension, setting, apiValue);
+    await ExtensionPreferencesManager.setSetting(extension.id, setting, apiValue);
 
     let checkResetPrefs = (method) => {
       let prefNames = settingObj.prefNames;
       for (let i = 0; i < prefNames.length; i++) {
         if (i === 0) {
           equal(Preferences.get(prefNames[0]), manualValue,
                 `${method} did not change a manually set pref.`);
         } else {
@@ -236,44 +236,44 @@ add_task(async function test_preference_
                 `${method} did not change another pref when a pref was manually set.`);
         }
       }
     };
 
     // Manually set the preference to a different value.
     Preferences.set(settingObj.prefNames[0], manualValue);
 
-    await ExtensionPreferencesManager.disableAll(extension);
+    await ExtensionPreferencesManager.disableAll(extension.id);
     checkResetPrefs("disableAll");
 
-    await ExtensionPreferencesManager.enableAll(extension);
+    await ExtensionPreferencesManager.enableAll(extension.id);
     checkResetPrefs("enableAll");
 
-    await ExtensionPreferencesManager.removeAll(extension);
+    await ExtensionPreferencesManager.removeAll(extension.id);
     checkResetPrefs("removeAll");
   }
 
   // Test with an uninitialized pref.
   let setting = "singlePref";
   let settingObj = SETTINGS[setting];
   let pref = settingObj.prefNames[0];
   let newValue = "newValue";
   Preferences.reset(pref);
-  await ExtensionPreferencesManager.setSetting(extensions[1], setting, newValue);
+  await ExtensionPreferencesManager.setSetting(extensions[1].id, setting, newValue);
   equal(Preferences.get(pref), settingObj.valueFn(pref, newValue),
     "Uninitialized pref is set.");
-  await ExtensionPreferencesManager.removeSetting(extensions[1], setting);
+  await ExtensionPreferencesManager.removeSetting(extensions[1].id, setting);
   ok(!Preferences.has(pref), "removeSetting removed the pref.");
 
   // Test levelOfControl with a locked pref.
   setting = "multiple_prefs";
   let prefToLock = SETTINGS[setting].prefNames[0];
   Preferences.lock(prefToLock, 1);
   ok(Preferences.locked(prefToLock), `Preference ${prefToLock} is locked.`);
-  let levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(extensions[1], setting);
+  let levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(extensions[1].id, setting);
   equal(
     levelOfControl,
     "not_controllable",
     "getLevelOfControl returns correct levelOfControl when a pref is locked.");
 
   for (let extension of testExtensions) {
     await extension.unload();
   }
--- a/toolkit/components/extensions/test/xpcshell/test_ext_extensionSettingsStore.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_extensionSettingsStore.js
@@ -85,347 +85,347 @@ add_task(async function test_settings_st
 
   // Initialize the SettingsStore.
   await ExtensionSettingsStore.initialize();
 
   // Add a setting for the second oldest extension, where it is the only setting for a key.
   for (let key of KEY_LIST) {
     let extensionIndex = 1;
     let itemToAdd = ITEMS[key][extensionIndex];
-    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controllable_by_this_extension",
       "getLevelOfControl returns correct levelOfControl with no settings set for a key.");
     let item = await ExtensionSettingsStore.addSetting(
-      extensions[extensionIndex], TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
+      extensions[extensionIndex].id, TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
     expectedCallbackCount++;
     equal(callbackCount,
       expectedCallbackCount,
       "initialValueCallback called the expected number of times.");
     deepEqual(item, itemToAdd, "Adding initial item for a key returns that item.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       itemToAdd,
       "getSetting returns correct item with only one item in the list.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_this_extension",
       "getLevelOfControl returns correct levelOfControl with only one item in the list.");
-    ok(ExtensionSettingsStore.hasSetting(extensions[extensionIndex], TEST_TYPE, key),
+    ok(ExtensionSettingsStore.hasSetting(extensions[extensionIndex].id, TEST_TYPE, key),
        "hasSetting returns the correct value when an extension has a setting set.");
   }
 
   // Add a setting for the oldest extension.
   for (let key of KEY_LIST) {
     let extensionIndex = 0;
     let itemToAdd = ITEMS[key][extensionIndex];
     let item = await ExtensionSettingsStore.addSetting(
-      extensions[extensionIndex], TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
+      extensions[extensionIndex].id, TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
     equal(callbackCount,
       expectedCallbackCount,
       "initialValueCallback called the expected number of times.");
     equal(item, null, "An older extension adding a setting for a key returns null");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][1],
       "getSetting returns correct item with more than one item in the list.");
-    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_other_extensions",
       "getLevelOfControl returns correct levelOfControl when another extension is in control.");
   }
 
   // Reload the settings store to emulate a browser restart.
   await ExtensionSettingsStore._reloadFile();
 
   // Add a setting for the newest extension.
   for (let key of KEY_LIST) {
     let extensionIndex = 2;
     let itemToAdd = ITEMS[key][extensionIndex];
-    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controllable_by_this_extension",
       "getLevelOfControl returns correct levelOfControl for a more recent extension.");
     let item = await ExtensionSettingsStore.addSetting(
-      extensions[extensionIndex], TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
+      extensions[extensionIndex].id, TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
     equal(callbackCount,
       expectedCallbackCount,
       "initialValueCallback called the expected number of times.");
     deepEqual(item, itemToAdd, "Adding item for most recent extension returns that item.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][2],
       "getSetting returns correct item with more than one item in the list.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_this_extension",
       "getLevelOfControl returns correct levelOfControl when this extension is in control.");
   }
 
   for (let extension of extensions) {
-    let items = await ExtensionSettingsStore.getAllForExtension(extension, TEST_TYPE);
+    let items = await ExtensionSettingsStore.getAllForExtension(extension.id, TEST_TYPE);
     deepEqual(items, KEY_LIST, "getAllForExtension returns expected keys.");
   }
 
   // Attempting to remove a setting that has not been set should *not* throw an exception.
-  let removeResult = await ExtensionSettingsStore.removeSetting(extensions[0], "myType", "unset_key");
+  let removeResult = await ExtensionSettingsStore.removeSetting(extensions[0].id, "myType", "unset_key");
   equal(removeResult, null, "Removing a setting that was not previously set returns null.");
 
   // Attempting to disable a setting that has not been set should throw an exception.
-  Assert.throws(() => ExtensionSettingsStore.disable(extensions[0], "myType", "unset_key"),
+  Assert.throws(() => ExtensionSettingsStore.disable(extensions[0].id, "myType", "unset_key"),
                 /Cannot alter the setting for myType:unset_key as it does not exist/,
                 "disable rejects with an unset key.");
 
   // Attempting to enable a setting that has not been set should throw an exception.
-  Assert.throws(() => ExtensionSettingsStore.enable(extensions[0], "myType", "unset_key"),
+  Assert.throws(() => ExtensionSettingsStore.enable(extensions[0].id, "myType", "unset_key"),
                 /Cannot alter the setting for myType:unset_key as it does not exist/,
                 "enable rejects with an unset key.");
 
   let expectedKeys = KEY_LIST;
   // Disable the non-top item for a key.
   for (let key of KEY_LIST) {
     let extensionIndex = 0;
     let item = await ExtensionSettingsStore.addSetting(
-      extensions[extensionIndex], TEST_TYPE, key, "new value", initialValue);
+      extensions[extensionIndex].id, TEST_TYPE, key, "new value", initialValue);
     equal(callbackCount,
       expectedCallbackCount,
       "initialValueCallback called the expected number of times.");
     equal(item, null, "Updating non-top item for a key returns null");
-    item = await ExtensionSettingsStore.disable(extensions[extensionIndex], TEST_TYPE, key);
+    item = await ExtensionSettingsStore.disable(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(item, null, "Disabling non-top item for a key returns null.");
-    let allForExtension = await ExtensionSettingsStore.getAllForExtension(extensions[extensionIndex], TEST_TYPE);
+    let allForExtension = await ExtensionSettingsStore.getAllForExtension(extensions[extensionIndex].id, TEST_TYPE);
     deepEqual(allForExtension, expectedKeys, "getAllForExtension returns expected keys after a disable.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][2],
       "getSetting returns correct item after a disable.");
-    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_other_extensions",
       "getLevelOfControl returns correct levelOfControl after disabling of non-top item.");
   }
 
   // Re-enable the non-top item for a key.
   for (let key of KEY_LIST) {
     let extensionIndex = 0;
-    let item = await ExtensionSettingsStore.enable(extensions[extensionIndex], TEST_TYPE, key);
+    let item = await ExtensionSettingsStore.enable(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(item, null, "Enabling non-top item for a key returns null.");
-    let allForExtension = await ExtensionSettingsStore.getAllForExtension(extensions[extensionIndex], TEST_TYPE);
+    let allForExtension = await ExtensionSettingsStore.getAllForExtension(extensions[extensionIndex].id, TEST_TYPE);
     deepEqual(allForExtension, expectedKeys, "getAllForExtension returns expected keys after an enable.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][2],
       "getSetting returns correct item after an enable.");
-    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_other_extensions",
       "getLevelOfControl returns correct levelOfControl after enabling of non-top item.");
   }
 
   // Remove the non-top item for a key.
   for (let key of KEY_LIST) {
     let extensionIndex = 0;
-    let item = await ExtensionSettingsStore.removeSetting(extensions[extensionIndex], TEST_TYPE, key);
+    let item = await ExtensionSettingsStore.removeSetting(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(item, null, "Removing non-top item for a key returns null.");
     expectedKeys = expectedKeys.filter(expectedKey => expectedKey != key);
-    let allForExtension = await ExtensionSettingsStore.getAllForExtension(extensions[extensionIndex], TEST_TYPE);
+    let allForExtension = await ExtensionSettingsStore.getAllForExtension(extensions[extensionIndex].id, TEST_TYPE);
     deepEqual(allForExtension, expectedKeys, "getAllForExtension returns expected keys after a removal.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][2],
       "getSetting returns correct item after a removal.");
-    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
+    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_other_extensions",
       "getLevelOfControl returns correct levelOfControl after removal of non-top item.");
-    ok(!ExtensionSettingsStore.hasSetting(extensions[extensionIndex], TEST_TYPE, key),
+    ok(!ExtensionSettingsStore.hasSetting(extensions[extensionIndex].id, TEST_TYPE, key),
        "hasSetting returns the correct value when an extension does not have a setting set.");
   }
 
   for (let key of KEY_LIST) {
     // Disable the top item for a key.
-    let item = await ExtensionSettingsStore.disable(extensions[2], TEST_TYPE, key);
+    let item = await ExtensionSettingsStore.disable(extensions[2].id, TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][1],
       "Disabling top item for a key returns the new top item.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][1],
       "getSetting returns correct item after a disable.");
-    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[2], TEST_TYPE, key);
+    let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[2].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controllable_by_this_extension",
       "getLevelOfControl returns correct levelOfControl after disabling of top item.");
 
     // Re-enable the top item for a key.
-    item = await ExtensionSettingsStore.enable(extensions[2], TEST_TYPE, key);
+    item = await ExtensionSettingsStore.enable(extensions[2].id, TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][2],
       "Re-enabling top item for a key returns the old top item.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][2],
       "getSetting returns correct item after an enable.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[2], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[2].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_this_extension",
       "getLevelOfControl returns correct levelOfControl after re-enabling top item.");
 
     // Remove the top item for a key.
-    item = await ExtensionSettingsStore.removeSetting(extensions[2], TEST_TYPE, key);
+    item = await ExtensionSettingsStore.removeSetting(extensions[2].id, TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][1],
       "Removing top item for a key returns the new top item.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       ITEMS[key][1],
       "getSetting returns correct item after a removal.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[2], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[2].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controllable_by_this_extension",
       "getLevelOfControl returns correct levelOfControl after removal of top item.");
 
     // Add a setting for the current top item.
     let itemToAdd = {key, value: `new-${key}`, id: "@second"};
     item = await ExtensionSettingsStore.addSetting(
-      extensions[1], TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
+      extensions[1].id, TEST_TYPE, itemToAdd.key, itemToAdd.value, initialValue);
     equal(callbackCount,
       expectedCallbackCount,
       "initialValueCallback called the expected number of times.");
     deepEqual(
       item,
       itemToAdd,
       "Updating top item for a key returns that item.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       itemToAdd,
       "getSetting returns correct item after updating.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_this_extension",
       "getLevelOfControl returns correct levelOfControl after updating.");
 
     // Disable the last remaining item for a key.
     let expectedItem = {key, initialValue: initialValue(key)};
     // We're using the callback to set the expected value, so we need to increment the
     // expectedCallbackCount.
     expectedCallbackCount++;
-    item = await ExtensionSettingsStore.disable(extensions[1], TEST_TYPE, key);
+    item = await ExtensionSettingsStore.disable(extensions[1].id, TEST_TYPE, key);
     deepEqual(
       item,
       expectedItem,
       "Disabling last item for a key returns the initial value.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       expectedItem,
       "getSetting returns the initial value after all are disabled.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controllable_by_this_extension",
       "getLevelOfControl returns correct levelOfControl after all are disabled.");
 
     // Re-enable the last remaining item for a key.
-    item = await ExtensionSettingsStore.enable(extensions[1], TEST_TYPE, key);
+    item = await ExtensionSettingsStore.enable(extensions[1].id, TEST_TYPE, key);
     deepEqual(
       item,
       itemToAdd,
       "Re-enabling last item for a key returns the old value.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       itemToAdd,
       "getSetting returns expected value after re-enabling.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controlled_by_this_extension",
       "getLevelOfControl returns correct levelOfControl after re-enabling.");
 
     // Remove the last remaining item for a key.
-    item = await ExtensionSettingsStore.removeSetting(extensions[1], TEST_TYPE, key);
+    item = await ExtensionSettingsStore.removeSetting(extensions[1].id, TEST_TYPE, key);
     deepEqual(
       item,
       expectedItem,
       "Removing last item for a key returns the initial value.");
     item = await ExtensionSettingsStore.getSetting(TEST_TYPE, key);
     deepEqual(
       item,
       null,
       "getSetting returns null after all are removed.");
-    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1], TEST_TYPE, key);
+    levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1].id, TEST_TYPE, key);
     equal(
       levelOfControl,
       "controllable_by_this_extension",
       "getLevelOfControl returns correct levelOfControl after all are removed.");
 
     // Attempting to remove a setting that has had all extensions removed should *not* throw an exception.
-    removeResult = await ExtensionSettingsStore.removeSetting(extensions[1], TEST_TYPE, key);
+    removeResult = await ExtensionSettingsStore.removeSetting(extensions[1].id, TEST_TYPE, key);
     equal(removeResult, null, "Removing a setting that has had all extensions removed returns null.");
   }
 
   // Test adding a setting with a value in callbackArgument.
   let extensionIndex = 0;
   let testKey = "callbackArgumentKey";
   let callbackArgumentValue = Date.now();
   // Add the setting.
   let item = await ExtensionSettingsStore.addSetting(
-    extensions[extensionIndex], TEST_TYPE, testKey, 1, initialValue, callbackArgumentValue);
+    extensions[extensionIndex].id, TEST_TYPE, testKey, 1, initialValue, callbackArgumentValue);
   expectedCallbackCount++;
   equal(callbackCount,
     expectedCallbackCount,
     "initialValueCallback called the expected number of times.");
   // Remove the setting which should return the initial value.
   let expectedItem = {key: testKey, initialValue: initialValue(callbackArgumentValue)};
   // We're using the callback to set the expected value, so we need to increment the
   // expectedCallbackCount.
   expectedCallbackCount++;
-  item = await ExtensionSettingsStore.removeSetting(extensions[extensionIndex], TEST_TYPE, testKey);
+  item = await ExtensionSettingsStore.removeSetting(extensions[extensionIndex].id, TEST_TYPE, testKey);
   deepEqual(
     item,
     expectedItem,
     "Removing last item for a key returns the initial value.");
   item = await ExtensionSettingsStore.getSetting(TEST_TYPE, testKey);
   deepEqual(
     item,
     null,
     "getSetting returns null after all are removed.");
 
   item = await ExtensionSettingsStore.getSetting(TEST_TYPE, "not a key");
   equal(
     item,
     null,
     "getSetting returns a null item if the setting does not have any records.");
-  let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1], TEST_TYPE, "not a key");
+  let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[1].id, TEST_TYPE, "not a key");
   equal(
     levelOfControl,
     "controllable_by_this_extension",
     "getLevelOfControl returns correct levelOfControl if the setting does not have any records.");
 
   for (let extension of testExtensions) {
     await extension.unload();
   }
@@ -472,56 +472,56 @@ add_task(async function test_settings_st
 
   // Initialize the SettingsStore.
   await ExtensionSettingsStore.initialize();
 
   equal(null, ExtensionSettingsStore.getSetting(type, key),
         "getSetting is initially null");
 
   let item = await ExtensionSettingsStore.addSetting(
-    one, type, key, "one", initialCallback);
+    one.id, type, key, "one", initialCallback);
   deepEqual({key, value: "one", id: one.id}, item,
             "addSetting returns the first set item");
 
   item = await ExtensionSettingsStore.addSetting(
-    two, type, key, "two", initialCallback);
+    two.id, type, key, "two", initialCallback);
   deepEqual({key, value: "two", id: two.id}, item,
             "addSetting returns the second set item");
 
   item = await ExtensionSettingsStore.addSetting(
-    three, type, key, "three", initialCallback);
+    three.id, type, key, "three", initialCallback);
   deepEqual({key, value: "three", id: three.id}, item,
             "addSetting returns the third set item");
 
   deepEqual(item, ExtensionSettingsStore.getSetting(type, key),
             "getSetting returns the third set item");
 
   ExtensionSettingsStore.setByUser(type, key);
   deepEqual({key, initialValue: "initial"}, ExtensionSettingsStore.getSetting(type, key),
             "getSetting returns the initial value after being set by user");
 
-  item = ExtensionSettingsStore.enable(one, type, key);
+  item = ExtensionSettingsStore.enable(one.id, type, key);
   deepEqual({key, value: "one", id: one.id}, item,
             "enable returns the first set item after enable");
 
-  item = ExtensionSettingsStore.enable(three, type, key);
+  item = ExtensionSettingsStore.enable(three.id, type, key);
   deepEqual({key, value: "three", id: three.id}, item,
             "enable returns the third set item after enable");
 
-  item = ExtensionSettingsStore.enable(two, type, key);
+  item = ExtensionSettingsStore.enable(two.id, type, key);
   deepEqual(undefined, item,
             "enable returns undefined after enabling the second item");
 
   item = ExtensionSettingsStore.getSetting(type, key);
   deepEqual({key, value: "three", id: three.id}, item,
             "getSetting returns the third set item after enabling the second item");
 
-  ExtensionSettingsStore.removeSetting(three, type, key);
-  ExtensionSettingsStore.removeSetting(two, type, key);
-  ExtensionSettingsStore.removeSetting(one, type, key);
+  ExtensionSettingsStore.removeSetting(three.id, type, key);
+  ExtensionSettingsStore.removeSetting(two.id, type, key);
+  ExtensionSettingsStore.removeSetting(one.id, type, key);
 
   equal(null, ExtensionSettingsStore.getSetting(type, key),
         "getSetting returns null after removing all settings");
 
   for (let extension of testExtensions) {
     await extension.unload();
   }