Bug 1356828: Don't call getAddonById from the Pocket bootstrap scope. r?rhelmer draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 15 Apr 2017 11:59:58 -0700
changeset 563265 5c5cfd0ea49eddb994fdc29665ec4c6de82a6dfe
parent 563259 70aa167349c1d85f7fca09563dca02a433a79321
child 624431 acf4a46e8e5e8ad6a2e5e1fc273a0612ca8966b6
push id54254
push usermaglione.k@gmail.com
push dateSat, 15 Apr 2017 19:00:22 +0000
reviewersrhelmer
bugs1356828
milestone55.0a1
Bug 1356828: Don't call getAddonById from the Pocket bootstrap scope. r?rhelmer MozReview-Commit-ID: DJM1dOIA7X4
browser/extensions/pocket/bootstrap.js
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/browser/extensions/pocket/bootstrap.js
+++ b/browser/extensions/pocket/bootstrap.js
@@ -11,17 +11,17 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
                                   "resource:///modules/RecentWindow.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
                                   "resource:///modules/CustomizableUI.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
+XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
                                   "resource://gre/modules/AddonManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
                                   "resource://gre/modules/ReaderMode.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Pocket",
                                   "chrome://pocket/content/Pocket.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AboutPocket",
                                   "chrome://pocket/content/AboutPocket.jsm");
 XPCOMUtils.defineLazyGetter(this, "gPocketBundle", function() {
@@ -472,31 +472,30 @@ function prefObserver(aSubject, aTopic, 
   let enabled = Services.prefs.getBoolPref("extensions.pocket.enabled");
   if (enabled)
     PocketOverlay.startup(ADDON_ENABLE);
   else
     PocketOverlay.shutdown(ADDON_DISABLE);
 }
 
 function startup(data, reason) {
-  AddonManager.getAddonByID("isreaditlater@ideashower.com", addon => {
-    if (addon && addon.isActive)
-      return;
-    setDefaultPrefs();
-    // migrate enabled pref
-    if (Services.prefs.prefHasUserValue("browser.pocket.enabled")) {
-      Services.prefs.setBoolPref("extensions.pocket.enabled", Services.prefs.getBoolPref("browser.pocket.enabled"));
-      Services.prefs.clearUserPref("browser.pocket.enabled");
-    }
-    // watch pref change and enable/disable if necessary
-    Services.prefs.addObserver("extensions.pocket.enabled", prefObserver);
-    if (!Services.prefs.getBoolPref("extensions.pocket.enabled"))
-      return;
-    PocketOverlay.startup(reason);
-  });
+  if (AddonManagerPrivate.addonIsActive("isreaditlater@ideashower.com"))
+    return;
+
+  setDefaultPrefs();
+  // migrate enabled pref
+  if (Services.prefs.prefHasUserValue("browser.pocket.enabled")) {
+    Services.prefs.setBoolPref("extensions.pocket.enabled", Services.prefs.getBoolPref("browser.pocket.enabled"));
+    Services.prefs.clearUserPref("browser.pocket.enabled");
+  }
+  // watch pref change and enable/disable if necessary
+  Services.prefs.addObserver("extensions.pocket.enabled", prefObserver);
+  if (!Services.prefs.getBoolPref("extensions.pocket.enabled"))
+    return;
+  PocketOverlay.startup(reason);
 }
 
 function shutdown(data, reason) {
   // For speed sake, we should only do a shutdown if we're being disabled.
   // On an app shutdown, just let it fade away...
   if (reason != APP_SHUTDOWN) {
     Services.prefs.removeObserver("extensions.pocket.enabled", prefObserver);
     PocketOverlay.shutdown(reason);
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -3094,16 +3094,21 @@ var AddonManagerInternal = {
  * AddonManagerInternal for documentation however note that these methods are
  * subject to change at any time.
  */
 this.AddonManagerPrivate = {
   startup() {
     AddonManagerInternal.startup();
   },
 
+  addonIsActive(addonId) {
+    return AddonManagerInternal._getProviderByName("XPIProvider")
+                               .addonIsActive(addonId);
+  },
+
   get browserUpdated() {
     return gBrowserUpdated;
   },
 
   registerProvider(aProvider, aTypes) {
     AddonManagerInternal.registerProvider(aProvider, aTypes);
   },
 
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -2455,16 +2455,18 @@ this.XPIStates = {
     location.delete(aId);
     if (location.size == 0) {
       this.db.delete(aLocation);
     }
     this.save();
   },
 };
 
+const hasOwnProperty = Function.call.bind({}.hasOwnProperty);
+
 this.XPIProvider = {
   get name() {
     return "XPIProvider";
   },
 
   // An array of known install locations
   installLocations: null,
   // A dictionary of known install locations by name
@@ -2504,16 +2506,33 @@ this.XPIProvider = {
   // A Map from an add-on install to its ID
   _addonFileMap: new Map(),
   // Flag to know if ToolboxProcess.jsm has already been loaded by someone or not
   _toolboxProcessLoaded: false,
   // Have we started shutting down bootstrap add-ons?
   _closing: false,
 
   /**
+   * Returns true if the add-on with the given ID is currently active,
+   * without forcing the add-ons database to load.
+   *
+   * @param {string} addonId
+   *        The ID of the add-on to check.
+   * @returns {boolean}
+   */
+  addonIsActive(addonId) {
+    if (hasOwnProperty(this.bootstrappedAddons, addonId)) {
+      return true;
+    }
+
+    let [, state] = XPIStates.findAddon(addonId);
+    return state && state.enabled;
+  },
+
+  /**
    * Returns an array of the add-on values in `bootstrappedAddons`,
    * sorted so that all of an add-on's dependencies appear in the array
    * before itself.
    *
    * @returns {Array<object>}
    *   A sorted array of add-on objects. Each value is a copy of the
    *   corresponding value in the `bootstrappedAddons` object, with an
    *   additional `id` property, which corresponds to the key in that