Bug 1404584 wip convert settings and preferences code to ids draft
authorAndrew Swan <aswan@mozilla.com>
Tue, 24 Oct 2017 20:18:03 -0700
changeset 686980 4697c678cda68114a27d2eb51f171cf2d1f74ac3
parent 686974 b38fca30d5e00acdca6109a84e43bbb56f8c2ae7
child 686981 d78015c18f74939491365c3dcb40f103f1f2b4a1
push id86369
push useraswan@mozilla.com
push dateThu, 26 Oct 2017 18:05:35 +0000
bugs1404584
milestone58.0a1
Bug 1404584 wip convert settings and preferences code to ids 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;
     }
@@ -193,136 +193,136 @@ this.ExtensionPreferencesManager = {
     await ExtensionSettingsStore.initialize();
     return ExtensionSettingsStore.getTopExtensionId(STORE_TYPE, 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
@@ -335,37 +335,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
@@ -139,45 +139,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.`);
@@ -228,18 +227,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
@@ -250,22 +249,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: [],
@@ -295,87 +293,90 @@ 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");
   },
 
   /**
    * 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
@@ -389,58 +390,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");
@@ -20,29 +18,29 @@ const NEW_TAB_OVERRIDE_SETTING = "newTab
 
 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();
   }