Bug 1772099 - Part 9: Use plain object for lazy getter in toolkit/mozapps/extensions/internal/XPIProvider.jsm. r=kmag
authorTooru Fujisawa <arai_a@mac.com>
Tue, 07 Jun 2022 04:29:51 +0000
changeset 619876 50b5a2d9ff1e877573e3be01a6a49be39fc332c9
parent 619875 52aefe6ea99743be642d723078fed0b51873ee11
child 619877 2279f40961146d41e943e613a573a3ba3dbbbfc8
push id39810
push userccozmuta@mozilla.com
push dateTue, 07 Jun 2022 15:57:48 +0000
treeherdermozilla-central@f52e2ad948e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1772099
milestone103.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1772099 - Part 9: Use plain object for lazy getter in toolkit/mozapps/extensions/internal/XPIProvider.jsm. r=kmag Differential Revision: https://phabricator.services.mozilla.com/D147935
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -25,34 +25,36 @@ const { XPCOMUtils } = ChromeUtils.impor
 );
 const { AddonManager, AddonManagerPrivate } = ChromeUtils.import(
   "resource://gre/modules/AddonManager.jsm"
 );
 const { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
 
-XPCOMUtils.defineLazyModuleGetters(this, {
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
   AddonSettings: "resource://gre/modules/addons/AddonSettings.jsm",
   AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
   Dictionary: "resource://gre/modules/Extension.jsm",
   Extension: "resource://gre/modules/Extension.jsm",
   ExtensionData: "resource://gre/modules/Extension.jsm",
   Langpack: "resource://gre/modules/Extension.jsm",
   SitePermission: "resource://gre/modules/Extension.jsm",
   FileUtils: "resource://gre/modules/FileUtils.jsm",
   JSONFile: "resource://gre/modules/JSONFile.jsm",
   TelemetrySession: "resource://gre/modules/TelemetrySession.jsm",
 
   XPIDatabase: "resource://gre/modules/addons/XPIDatabase.jsm",
   XPIDatabaseReconcile: "resource://gre/modules/addons/XPIDatabase.jsm",
   XPIInstall: "resource://gre/modules/addons/XPIInstall.jsm",
 });
 
-XPCOMUtils.defineLazyServiceGetters(this, {
+XPCOMUtils.defineLazyServiceGetters(lazy, {
   aomStartup: [
     "@mozilla.org/addons/addon-manager-startup;1",
     "amIAddonManagerStartup",
   ],
   resProto: [
     "@mozilla.org/network/protocol;1?name=resource",
     "nsISubstitutingProtocolHandler",
   ],
@@ -126,26 +128,26 @@ const STARTUP_MTIME_SCOPES = [
 const NOTIFICATION_FLUSH_PERMISSIONS = "flush-pending-permissions";
 const XPI_PERMISSION = "install";
 
 const XPI_SIGNATURE_CHECK_PERIOD = 24 * 60 * 60;
 
 const DB_SCHEMA = 35;
 
 XPCOMUtils.defineLazyPreferenceGetter(
-  this,
+  lazy,
   "enabledScopesPref",
   PREF_EM_ENABLED_SCOPES,
   AddonManager.SCOPE_ALL
 );
 
-Object.defineProperty(this, "enabledScopes", {
+Object.defineProperty(lazy, "enabledScopes", {
   get() {
     // The profile location is always enabled
-    return enabledScopesPref | AddonManager.SCOPE_PROFILE;
+    return lazy.enabledScopesPref | AddonManager.SCOPE_PROFILE;
   },
 });
 
 function encoded(strings, ...values) {
   let result = [];
 
   for (let [i, string] of strings.entries()) {
     result.push(string);
@@ -176,18 +178,16 @@ const BOOTSTRAP_REASONS = {
 const ALL_XPI_TYPES = new Set([
   "dictionary",
   "extension",
   "locale",
   "sitepermission",
   "theme",
 ]);
 
-var gGlobalScope = this;
-
 /**
  * Valid IDs fit this pattern.
  */
 var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i;
 
 const { Log } = ChromeUtils.import("resource://gre/modules/Log.jsm");
 const LOGGER_ID = "addons.xpi";
 
@@ -361,17 +361,17 @@ function getURIForResourceInFile(aFile, 
 function buildJarURI(aJarfile, aPath) {
   let uri = Services.io.newFileURI(aJarfile);
   uri = "jar:" + uri.spec + "!/" + aPath;
   return Services.io.newURI(uri);
 }
 
 function maybeResolveURI(uri) {
   if (uri.schemeIs("resource")) {
-    return Services.io.newURI(resProto.resolveURI(uri));
+    return Services.io.newURI(lazy.resProto.resolveURI(uri));
   }
   return uri;
 }
 
 /**
  * Iterates over the entries in a given directory.
  *
  * Fails silently if the given directory does not exist.
@@ -564,17 +564,17 @@ class XPIState {
     return json;
   }
 
   get isWebExtension() {
     return this.loader == null;
   }
 
   get isPrivileged() {
-    return ExtensionData.getIsPrivileged({
+    return lazy.ExtensionData.getIsPrivileged({
       signedState: this.signedState,
       builtIn: this.location.isBuiltin,
       temporarilyInstalled: this.location.isTemporary,
     });
   }
 
   /**
    * Update the last modified time for an add-on on disk.
@@ -651,18 +651,18 @@ class XPIState {
     this.signedDate = aDBAddon.signedDate;
     this.file = aDBAddon._sourceBundle;
     this.rootURI = aDBAddon.rootURI;
 
     if ((aUpdated || mustGetMod) && this.file) {
       this.getModTime(this.file);
       if (this.lastModifiedTime != aDBAddon.updateDate) {
         aDBAddon.updateDate = this.lastModifiedTime;
-        if (XPIDatabase.initialized) {
-          XPIDatabase.saveChanges();
+        if (lazy.XPIDatabase.initialized) {
+          lazy.XPIDatabase.saveChanges();
         }
       }
     }
   }
 }
 
 /**
  * Manages the state data for add-ons in a given install location.
@@ -1002,17 +1002,17 @@ class DirectoryLocation extends XPIState
     this.locked = locked;
     this._isSystem = system;
   }
 
   makeInstaller() {
     if (this.locked) {
       return null;
     }
-    return new XPIInstall.DirectoryInstaller(this);
+    return new lazy.XPIInstall.DirectoryInstaller(this);
   }
 
   /**
    * Reads a single-line file containing the path to a directory, and
    * returns an nsIFile pointing to that directory, if successful.
    *
    * @param {nsIFile} aFile
    *        The file containing the directory path
@@ -1218,17 +1218,17 @@ class SystemAddonLocation extends Direct
       this.installer.resetAddonSet();
     }
   }
 
   makeInstaller() {
     if (this.locked) {
       return null;
     }
-    return new XPIInstall.SystemAddonInstaller(this);
+    return new lazy.XPIInstall.SystemAddonInstaller(this);
   }
 
   /**
    * Reads the current set of system add-ons
    *
    * @returns {Object}
    */
   static _loadAddonSet() {
@@ -1391,17 +1391,17 @@ var XPIStates = {
   /**
    * Load extension state data from addonStartup.json.
    *
    * @returns {Object}
    */
   loadExtensionState() {
     let state;
     try {
-      state = aomStartup.readStartupData();
+      state = lazy.aomStartup.readStartupData();
     } catch (e) {
       logger.warn("Error parsing extensions state: ${error}", { error: e });
     }
 
     // When upgrading from a build prior to bug 857456, convert startup
     // metadata.
     let done = false;
     for (let location of Object.values(state || {})) {
@@ -1474,30 +1474,33 @@ var XPIStates = {
 
       if (!loc.enumerable) {
         continue;
       }
 
       // Don't bother scanning scopes where we don't have addons installed if they
       // do not allow sideloading new addons.  Once we have an addon in one of those
       // locations, we need to check the location for changes (updates/deletions).
-      if (!loc.size && !(loc.scope & AddonSettings.SCOPES_SIDELOAD)) {
+      if (!loc.size && !(loc.scope & lazy.AddonSettings.SCOPES_SIDELOAD)) {
         continue;
       }
 
       let knownIds = new Set(loc.keys());
       for (let [id, file] of loc.readAddons()) {
         knownIds.delete(id);
 
         let xpiState = loc.get(id);
         if (!xpiState) {
           // If the location is not supported for sideloading, skip new
           // addons.  We handle this here so changes for existing sideloads
           // will function.
-          if (!loc.isSystem && !(loc.scope & AddonSettings.SCOPES_SIDELOAD)) {
+          if (
+            !loc.isSystem &&
+            !(loc.scope & lazy.AddonSettings.SCOPES_SIDELOAD)
+          ) {
             continue;
           }
           logger.debug("New add-on ${id} in ${loc}", { id, loc: loc.name });
 
           changed = true;
           xpiState = loc.addFile(id, file);
           if (!loc.isSystem) {
             this.sideLoadedAddons.set(id, xpiState);
@@ -1636,17 +1639,17 @@ var XPIStates = {
     aAddon.location.addAddon(aAddon);
   },
 
   /**
    * Save the current state of installed add-ons.
    */
   save() {
     if (!this._jsonFile) {
-      this._jsonFile = new JSONFile({
+      this._jsonFile = new lazy.JSONFile({
         path: PathUtils.join(
           Services.dirsvc.get("ProfD", Ci.nsIFile).path,
           FILE_XPI_STATES
         ),
         finalizeAt: AddonManagerPrivate.finalShutdown,
         compression: "lz4",
       });
       this._jsonFile.data = this;
@@ -1805,17 +1808,17 @@ class BootstrapScope {
       } else if (aMethod == "shutdown") {
         this.started = false;
 
         // Extensions are automatically deinitialized in the correct order at shutdown.
         if (aReason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
           this._pendingDisable = true;
           for (let addon of XPIProvider.getDependentAddons(this.addon)) {
             if (addon.active) {
-              await XPIDatabase.updateAddonDisabledState(addon);
+              await lazy.XPIDatabase.updateAddonDisabledState(addon);
             }
           }
         }
       }
 
       let params = {
         id: addon.id,
         version: addon.version,
@@ -1855,17 +1858,17 @@ class BootstrapScope {
           );
         }
       }
       return result;
     } finally {
       // Extensions are automatically initialized in the correct order at startup.
       if (aMethod == "startup" && aReason != BOOTSTRAP_REASONS.APP_STARTUP) {
         for (let addon of XPIProvider.getDependentAddons(this.addon)) {
-          XPIDatabase.updateAddonDisabledState(addon);
+          lazy.XPIDatabase.updateAddonDisabledState(addon);
         }
       }
     }
   }
 
   // No-op method to be overridden by tests.
   _beforeCallBootstrapMethod() {}
 
@@ -1891,29 +1894,29 @@ class BootstrapScope {
     }
 
     logger.debug(`Loading bootstrap scope from ${this.addon.rootURI}`);
 
     if (this.addon.isWebExtension) {
       switch (this.addon.type) {
         case "extension":
         case "theme":
-          this.scope = Extension.getBootstrapScope();
+          this.scope = lazy.Extension.getBootstrapScope();
           break;
 
         case "sitepermission":
-          this.scope = SitePermission.getBootstrapScope();
+          this.scope = lazy.SitePermission.getBootstrapScope();
           break;
 
         case "locale":
-          this.scope = Langpack.getBootstrapScope();
+          this.scope = lazy.Langpack.getBootstrapScope();
           break;
 
         case "dictionary":
-          this.scope = Dictionary.getBootstrapScope();
+          this.scope = lazy.Dictionary.getBootstrapScope();
           break;
 
         default:
           throw new Error(`Unknown webextension type ${this.addon.type}`);
       }
     } else {
       let loader = AddonManagerPrivate.externalExtensionLoaders.get(
         this.addon.loader
@@ -2061,17 +2064,17 @@ class BootstrapScope {
       await this.shutdown(reason, extraArgs);
     }
     if (!callUpdate) {
       this.callBootstrapMethod("uninstall", reason, extraArgs);
     }
     this.unloadBootstrapScope();
 
     if (this.file) {
-      XPIInstall.flushJarCache(this.file);
+      lazy.XPIInstall.flushJarCache(this.file);
     }
   }
 
   /**
    * Calls the appropriate sequence of shutdown, uninstall, update,
    * startup, and install methods for updating the current scope's
    * add-on to the given new add-on, depending on the current state of
    * the scope.
@@ -2087,17 +2090,17 @@ class BootstrapScope {
    *        the old add-on and installing the new one. This callback
    *        should update any database state which is necessary for the
    *        startup of the new add-on.
    * @returns {Promise}
    *        Resolves when all required bootstrap callbacks have
    *        completed.
    */
   async update(newAddon, startup = false, updateCallback) {
-    let reason = XPIInstall.newVersionReason(
+    let reason = lazy.XPIInstall.newVersionReason(
       this.addon.version,
       newAddon.version
     );
 
     let callUpdate = this.addon.isWebExtension && newAddon.isWebExtension;
 
     // BootstrapScope gets either an XPIState instance or an AddonInternal
     // instance, when we update, we need the latter to access permissions
@@ -2109,21 +2112,21 @@ class BootstrapScope {
       newVersion: newAddon.version,
     };
 
     // If we're updating an extension, we may need to read data to
     // calculate permission changes.
     if (callUpdate && existingAddon.type === "extension") {
       if (this.addon instanceof XPIState) {
         // The existing addon will be cached in the database.
-        existingAddon = await XPIDatabase.getAddonByID(this.addon.id);
+        existingAddon = await lazy.XPIDatabase.getAddonByID(this.addon.id);
       }
 
       if (newAddon instanceof XPIState) {
-        newAddon = await XPIInstall.loadManifestFromFile(
+        newAddon = await lazy.XPIInstall.loadManifestFromFile(
           newAddon.file,
           newAddon.location
         );
       }
 
       Object.assign(extraArgs, {
         userPermissions: newAddon.userPermissions,
         optionalPermissions: newAddon.optionalPermissions,
@@ -2171,18 +2174,18 @@ var XPIProvider = {
   databaseReady: Promise.all([dbReadyPromise, providerReadyPromise]),
 
   // Check if the XPIDatabase has been loaded (without actually
   // triggering unwanted imports or I/O)
   get isDBLoaded() {
     // Make sure we don't touch the XPIDatabase getter before it's
     // actually loaded, and force an early load.
     return (
-      (Object.getOwnPropertyDescriptor(gGlobalScope, "XPIDatabase").value &&
-        XPIDatabase.initialized) ||
+      (Object.getOwnPropertyDescriptor(lazy, "XPIDatabase").value &&
+        lazy.XPIDatabase.initialized) ||
       false
     );
   },
 
   /**
    * Returns true if the add-on with the given ID is currently active,
    * without forcing the add-ons database to load.
    *
@@ -2251,35 +2254,35 @@ var XPIProvider = {
       this._telemetryDetails[aId] = {};
     }
     Object.assign(this._telemetryDetails[aId], aPayload);
   },
 
   setupInstallLocations(aAppChanged) {
     function DirectoryLoc(aName, aScope, aKey, aPaths, aLocked, aIsSystem) {
       try {
-        var dir = FileUtils.getDir(aKey, aPaths);
+        var dir = lazy.FileUtils.getDir(aKey, aPaths);
       } catch (e) {
         return null;
       }
       return new DirectoryLocation(aName, dir, aScope, aLocked, aIsSystem);
     }
 
     function SystemDefaultsLoc(name, scope, key, paths) {
       try {
-        var dir = FileUtils.getDir(key, paths);
+        var dir = lazy.FileUtils.getDir(key, paths);
       } catch (e) {
         return null;
       }
       return new SystemAddonDefaults(name, dir, scope);
     }
 
     function SystemLoc(aName, aScope, aKey, aPaths) {
       try {
-        var dir = FileUtils.getDir(aKey, aPaths);
+        var dir = lazy.FileUtils.getDir(aKey, aPaths);
       } catch (e) {
         return null;
       }
       return new SystemAddonLocation(aName, dir, aScope, aAppChanged !== false);
     }
 
     function RegistryLoc(aName, aScope, aKey) {
       if ("nsIWindowsRegKey" in Ci) {
@@ -2376,17 +2379,17 @@ var XPIProvider = {
         RegistryLoc,
         "winreg-app-global",
         AddonManager.SCOPE_SYSTEM,
         "ROOT_KEY_LOCAL_MACHINE",
       ],
     ];
 
     for (let [constructor, name, scope, ...args] of locations) {
-      if (!scope || enabledScopes & scope) {
+      if (!scope || lazy.enabledScopes & scope) {
         try {
           let loc = constructor(name, scope, ...args);
           if (loc) {
             XPIStates.addLocation(name, loc);
           }
         } catch (e) {
           logger.warn(
             `Failed to add ${constructor.name} install location ${name}`,
@@ -2405,45 +2408,45 @@ var XPIProvider = {
     this.dictionaries = {};
     for (let [lang, path] of Object.entries(
       this.builtInAddons.dictionaries || {}
     )) {
       path = path.slice(0, -4) + ".aff";
       let uri = Services.io.newURI(`resource://gre/${path}`);
 
       this.dictionaries[lang] = uri;
-      spellCheck.addDictionary(lang, uri);
+      lazy.spellCheck.addDictionary(lang, uri);
     }
   },
 
   /**
    * Unregisters the dictionaries in the given object, and re-registers
    * any built-in dictionaries in their place, when they exist.
    *
    * @param {Object<nsIURI>} aDicts
    *        An object containing a property with a dictionary language
    *        code and a nsIURI value for each dictionary to be
    *        unregistered.
    */
   unregisterDictionaries(aDicts) {
-    let origDicts = spellCheck.dictionaries.slice();
+    let origDicts = lazy.spellCheck.dictionaries.slice();
     let toRemove = [];
 
     for (let [lang, uri] of Object.entries(aDicts)) {
       if (
-        spellCheck.removeDictionary(lang, uri) &&
+        lazy.spellCheck.removeDictionary(lang, uri) &&
         this.dictionaries.hasOwnProperty(lang)
       ) {
-        spellCheck.addDictionary(lang, this.dictionaries[lang]);
+        lazy.spellCheck.addDictionary(lang, this.dictionaries[lang]);
       } else {
         toRemove.push(lang);
       }
     }
 
-    spellCheck.dictionaries = origDicts.filter(
+    lazy.spellCheck.dictionaries = origDicts.filter(
       lang => !toRemove.includes(lang)
     );
   },
 
   /**
    * Starts the XPI provider initializes the install locations and prefs.
    *
    * @param {boolean?} aAppChanged
@@ -2577,17 +2580,17 @@ var XPIProvider = {
           "XPI-BOOTSTRAP",
           "startup failed",
           e
         );
       }
 
       // Let these shutdown a little earlier when they still have access to most
       // of XPCOM
-      AsyncShutdown.quitApplicationGranted.addBlocker(
+      lazy.AsyncShutdown.quitApplicationGranted.addBlocker(
         "XPIProvider shutdown",
         async () => {
           XPIProvider._closing = true;
 
           await XPIProvider.cleanupTemporaryAddons();
           for (let addon of XPIProvider.sortBootstrappedAddons().reverse()) {
             // If no scope has been loaded for this add-on then there is no need
             // to shut it down (should only happen when a bootstrapped add-on is
@@ -2604,26 +2607,26 @@ var XPIProvider = {
               reason = BOOTSTRAP_REASONS.ADDON_DISABLE;
             } else if (addon.location.name == KEY_APP_TEMPORARY) {
               reason = BOOTSTRAP_REASONS.ADDON_UNINSTALL;
               let existing = XPIStates.findAddon(
                 addon.id,
                 loc => !loc.isTemporary
               );
               if (existing) {
-                reason = XPIInstall.newVersionReason(
+                reason = lazy.XPIInstall.newVersionReason(
                   addon.version,
                   existing.version
                 );
               }
             }
 
             let scope = BootstrapScope.get(addon);
             let promise = scope.shutdown(reason);
-            AsyncShutdown.profileChangeTeardown.addBlocker(
+            lazy.AsyncShutdown.profileChangeTeardown.addBlocker(
               `Extension shutdown: ${addon.id}`,
               promise,
               {
                 fetchState: scope.fetchState.bind(scope),
               }
             );
           }
         }
@@ -2669,29 +2672,29 @@ var XPIProvider = {
           ) {
             return;
           }
 
           for (let event of EVENTS) {
             Services.obs.removeObserver(observer, event);
           }
 
-          XPIDatabase.asyncLoadDB();
+          lazy.XPIDatabase.asyncLoadDB();
         };
         for (let event of EVENTS) {
           Services.obs.addObserver(observer, event);
         }
       }
 
       AddonManagerPrivate.recordTimestamp("XPI_startup_end");
 
-      timerManager.registerTimer(
+      lazy.timerManager.registerTimer(
         "xpi-signature-verification",
         () => {
-          XPIDatabase.verifySignatures();
+          lazy.XPIDatabase.verifySignatures();
         },
         XPI_SIGNATURE_CHECK_PERIOD
       );
     } catch (e) {
       logger.error("startup failed", e);
       AddonManagerPrivate.recordException("XPI", "startup failed", e);
     }
   },
@@ -2704,32 +2707,32 @@ var XPIProvider = {
    */
   async shutdown() {
     logger.debug("shutdown");
 
     this.activeAddons.clear();
     this.allAppGlobal = true;
 
     // Stop anything we were doing asynchronously
-    XPIInstall.cancelAll();
-
-    for (let install of XPIInstall.installs) {
+    lazy.XPIInstall.cancelAll();
+
+    for (let install of lazy.XPIInstall.installs) {
       if (install.onShutdown()) {
         install.onShutdown();
       }
     }
 
     // If there are pending operations then we must update the list of active
     // add-ons
     if (Services.prefs.getBoolPref(PREF_PENDING_OPERATIONS, false)) {
-      XPIDatabase.updateActiveAddons();
+      lazy.XPIDatabase.updateActiveAddons();
       Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, false);
     }
 
-    await XPIDatabase.shutdown();
+    await lazy.XPIDatabase.shutdown();
   },
 
   cleanupTemporaryAddons() {
     let promises = [];
     let tempLocation = TemporaryInstallLocation;
     for (let [id, addon] of tempLocation.entries()) {
       tempLocation.delete(id);
 
@@ -2740,22 +2743,22 @@ var XPIProvider = {
         tempLocation.installer.uninstallAddon(id);
         tempLocation.removeAddon(id);
       };
 
       let promise;
       if (existing) {
         promise = bootstrap.update(existing, false, () => {
           cleanup();
-          XPIDatabase.makeAddonLocationVisible(id, existing.location);
+          lazy.XPIDatabase.makeAddonLocationVisible(id, existing.location);
         });
       } else {
         promise = bootstrap.uninstall().then(cleanup);
       }
-      AsyncShutdown.profileChangeTeardown.addBlocker(
+      lazy.AsyncShutdown.profileChangeTeardown.addBlocker(
         `Temporary extension shutdown: ${addon.id}`,
         promise
       );
       promises.push(promise);
     }
     return Promise.all(promises);
   },
 
@@ -2771,17 +2774,17 @@ var XPIProvider = {
     let data = Array.from(XPIStates.enabledAddons(), a => a.telemetryKey).join(
       ","
     );
 
     try {
       Services.appinfo.annotateCrashReport("Add-ons", data);
     } catch (e) {}
 
-    TelemetrySession.setAddOns(data);
+    lazy.TelemetrySession.setAddOns(data);
   },
 
   /**
    * Check the staging directories of install locations for any add-ons to be
    * installed or add-ons to be uninstalled.
    *
    * @param {Object} aManifests
    *         A dictionary to add detected install manifests to for the purpose
@@ -2802,17 +2805,17 @@ var XPIProvider = {
       // during cleanStagingDir.  Successful installs remove the files.
       let stagedFailureNames = [];
       let promises = [];
       for (let [id, metadata] of loc.getStagedAddons()) {
         loc.unstageAddon(id);
 
         aManifests[loc.name][id] = null;
         promises.push(
-          XPIInstall.installStagedAddon(id, metadata, loc).then(
+          lazy.XPIInstall.installStagedAddon(id, metadata, loc).then(
             addon => {
               aManifests[loc.name][id] = addon;
             },
             error => {
               delete aManifests[loc.name][id];
               stagedFailureNames.push(`${id}.xpi`);
 
               logger.error(
@@ -2856,17 +2859,19 @@ var XPIProvider = {
    *        The version of the application last run with this profile or null
    *        if it is a new profile or the version is unknown
    * @returns {boolean}
    *        True if any new add-ons were installed
    */
   installDistributionAddons(aManifests, aAppChanged, aOldAppVersion) {
     let distroDirs = [];
     try {
-      distroDirs.push(FileUtils.getDir(KEY_APP_DISTRIBUTION, [DIR_EXTENSIONS]));
+      distroDirs.push(
+        lazy.FileUtils.getDir(KEY_APP_DISTRIBUTION, [DIR_EXTENSIONS])
+      );
     } catch (e) {
       return false;
     }
 
     let availableLocales = [];
     for (let file of iterDirectory(distroDirs[0])) {
       if (file.isDirectory() && file.leafName.startsWith("locale-")) {
         availableLocales.push(file.leafName.replace("locale-", ""));
@@ -2915,17 +2920,22 @@ var XPIProvider = {
           Services.prefs.prefHasUserValue(PREF_BRANCH_INSTALLED_ADDON + id)
         ) {
           continue;
         }
 
         try {
           let loc = XPIStates.getLocation(KEY_APP_PROFILE);
           let addon = awaitPromise(
-            XPIInstall.installDistributionAddon(id, file, loc, aOldAppVersion)
+            lazy.XPIInstall.installDistributionAddon(
+              id,
+              file,
+              loc,
+              aOldAppVersion
+            )
           );
 
           if (addon) {
             // aManifests may contain a copy of a newly installed add-on's manifest
             // and we'll have overwritten that so instead cache our install manifest
             // which will later be put into the database in processFileChanges
             if (!(loc.name in aManifests)) {
               aManifests[loc.name] = {};
@@ -2952,28 +2962,28 @@ var XPIProvider = {
    * @param {string} aVersion
    *        The version of the add-on being registered.
    * @param {string} aBase
    *        A string containing the base URL.  Must be a resource: URL.
    * @returns {Promise<Addon>} a Promise that resolves when the addon is installed.
    */
   async maybeInstallBuiltinAddon(aID, aVersion, aBase) {
     let installed;
-    if (enabledScopes & BuiltInLocation.scope) {
+    if (lazy.enabledScopes & BuiltInLocation.scope) {
       let existing = BuiltInLocation.get(aID);
       if (!existing || existing.version != aVersion) {
         installed = this.installBuiltinAddon(aBase);
         this.startupPromises.push(installed);
       }
     }
     return installed;
   },
 
   getDependentAddons(aAddon) {
-    return Array.from(XPIDatabase.getAddons()).filter(addon =>
+    return Array.from(lazy.XPIDatabase.getAddons()).filter(addon =>
       addon.dependencies.includes(aAddon.id)
     );
   },
 
   /**
    * Checks for any changes that have occurred since the last time the
    * application was launched.
    *
@@ -3057,34 +3067,34 @@ var XPIProvider = {
       let extensionListChanged = false;
       // If the database needs to be updated then open it and then update it
       // from the filesystem
       if (updateReasons.length) {
         AddonManagerPrivate.recordSimpleMeasure(
           "XPIDB_startup_load_reasons",
           updateReasons
         );
-        XPIDatabase.syncLoadDB(false);
+        lazy.XPIDatabase.syncLoadDB(false);
         try {
-          extensionListChanged = XPIDatabaseReconcile.processFileChanges(
+          extensionListChanged = lazy.XPIDatabaseReconcile.processFileChanges(
             manifests,
             aAppChanged,
             aOldAppVersion,
             aOldPlatformVersion,
             updateReasons.includes("schemaChanged")
           );
         } catch (e) {
           logger.error("Failed to process extension changes at startup", e);
         }
       }
 
       // If the application crashed before completing any pending operations then
       // we should perform them now.
       if (extensionListChanged || hasPendingChanges) {
-        XPIDatabase.updateActiveAddons();
+        lazy.XPIDatabase.updateActiveAddons();
         return;
       }
 
       logger.debug("No changes found");
     } catch (e) {
       logger.error("Error during startup file checks", e);
     }
   },
@@ -3094,19 +3104,19 @@ var XPIProvider = {
    * prior to startup of the current session, were detected by a directory scan
    * of those locations, and are currently disabled.
    *
    * @returns {Promise<Array<Addon>>}
    */
   async getNewSideloads() {
     if (XPIStates.scanForChanges(false)) {
       // We detected changes. Update the database to account for them.
-      await XPIDatabase.asyncLoadDB(false);
-      XPIDatabaseReconcile.processFileChanges({}, false);
-      XPIDatabase.updateActiveAddons();
+      await lazy.XPIDatabase.asyncLoadDB(false);
+      lazy.XPIDatabaseReconcile.processFileChanges({}, false);
+      lazy.XPIDatabase.updateActiveAddons();
     }
 
     let addons = await Promise.all(
       Array.from(XPIStates.sideLoadedAddons.keys(), id => this.getAddonByID(id))
     );
 
     return addons.filter(
       addon =>
@@ -3186,17 +3196,17 @@ var XPIProvider = {
 
     return null;
   },
 
   async getAddonsByTypes(aTypes) {
     if (aTypes && !aTypes.some(type => ALL_XPI_TYPES.has(type))) {
       return [];
     }
-    return XPIDatabase.getAddonsByTypes(aTypes);
+    return lazy.XPIDatabase.getAddonsByTypes(aTypes);
   },
 
   /**
    * Called to get active Addons of a particular type
    *
    * @param {Array<string>?} aTypes
    *        An array of types to fetch. Can be null to get all types.
    * @returns {Promise<Array<Addon>>}
@@ -3235,61 +3245,61 @@ var XPIProvider = {
    * Notified when a preference we're interested in has changed.
    *
    * @see nsIObserver
    */
   observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case NOTIFICATION_FLUSH_PERMISSIONS:
         if (!aData || aData == XPI_PERMISSION) {
-          XPIDatabase.importPermissions();
+          lazy.XPIDatabase.importPermissions();
         }
         break;
 
       case "nsPref:changed":
         switch (aData) {
           case PREF_XPI_SIGNATURES_REQUIRED:
           case PREF_LANGPACK_SIGNATURES:
-            XPIDatabase.updateAddonAppDisabledStates();
+            lazy.XPIDatabase.updateAddonAppDisabledStates();
             break;
         }
     }
   },
 
   uninstallSystemProfileAddon(aID) {
     let location = XPIStates.getLocation(KEY_APP_SYSTEM_PROFILE);
-    return XPIInstall.uninstallAddonFromLocation(aID, location);
+    return lazy.XPIInstall.uninstallAddonFromLocation(aID, location);
   },
 };
 
 for (let meth of [
   "getInstallForFile",
   "getInstallForURL",
   "getInstallsByTypes",
   "installTemporaryAddon",
   "installBuiltinAddon",
   "isInstallAllowed",
   "isInstallEnabled",
   "updateSystemAddons",
   "stageLangpacksForAppUpdate",
 ]) {
   XPIProvider[meth] = function() {
-    return XPIInstall[meth](...arguments);
+    return lazy.XPIInstall[meth](...arguments);
   };
 }
 
 for (let meth of [
   "addonChanged",
   "getAddonByID",
   "getAddonBySyncGUID",
   "updateAddonRepositoryData",
   "updateAddonAppDisabledStates",
 ]) {
   XPIProvider[meth] = function() {
-    return XPIDatabase[meth](...arguments);
+    return lazy.XPIDatabase[meth](...arguments);
   };
 }
 
 var XPIInternal = {
   BOOTSTRAP_REASONS,
   BootstrapScope,
   BuiltInLocation,
   DB_SCHEMA,
@@ -3312,13 +3322,13 @@ var XPIInternal = {
   isXPI,
   iterDirectory,
   maybeResolveURI,
   migrateAddonLoader,
   resolveDBReady,
 
   // Used by tests to shut down AddonManager.
   overrideAsyncShutdown(mockAsyncShutdown) {
-    AsyncShutdown = mockAsyncShutdown;
+    lazy.AsyncShutdown = mockAsyncShutdown;
   },
 };
 
 AddonManagerPrivate.registerProvider(XPIProvider, Array.from(ALL_XPI_TYPES));