Bug 1369801 - use DevToolsShim in XPIProvider.jsm draft
authorJulian Descottes <jdescottes@mozilla.com>
Tue, 20 Jun 2017 09:56:47 +0200
changeset 599187 0327e167cef1525d9a00f7822900724efe052bab
parent 599186 0a45960242b66b8bf35e44ee32a80f487235106c
child 599188 a7866955243b51c1fee315a0a8acfbaceb6b373f
push id65442
push userjdescottes@mozilla.com
push dateThu, 22 Jun 2017 19:44:34 +0000
bugs1369801
milestone56.0a1
Bug 1369801 - use DevToolsShim in XPIProvider.jsm MozReview-Commit-ID: 3WqIEXCnXOc
devtools/client/aboutdebugging/test/addons/unpacked/install.rdf
devtools/client/framework/devtools.js
devtools/shim/DevToolsShim.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/devtools/client/aboutdebugging/test/addons/unpacked/install.rdf
+++ b/devtools/client/aboutdebugging/test/addons/unpacked/install.rdf
@@ -9,16 +9,17 @@
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
   <Description about="urn:mozilla:install-manifest"
                em:id="test-devtools@mozilla.org"
                em:name="test-devtools"
                em:version="1.0"
                em:type="2"
                em:creator="Mozilla">
 
+    <em:multiprocessCompatible>true</em:multiprocessCompatible>
     <em:bootstrap>true</em:bootstrap>
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>44.0a1</em:minVersion>
         <em:maxVersion>*</em:maxVersion>
       </Description>
     </em:targetApplication>
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -570,16 +570,30 @@ DevTools.prototype = {
    *
    * Create a BrowserToolbox process linked to the provided addon id.
    */
   initBrowserToolboxProcessForAddon: function (addonID) {
     BrowserToolboxProcess.init({ addonID });
   },
 
   /**
+   * Compatibility layer for XPIProvider.jsm.
+   */
+  isToolboxProcessLoaded: function () {
+    return Cu.isModuleLoaded("resource://devtools/client/framework/ToolboxProcess.jsm");
+  },
+
+  /**
+   * Compatibility layer for XPIProvider.jsm.
+   */
+  getBrowserToolboxProcess: function () {
+    return BrowserToolboxProcess;
+  },
+
+  /**
    * Either the SDK Loader has been destroyed by the add-on contribution
    * workflow, or firefox is shutting down.
 
    * @param {boolean} shuttingDown
    *        True if firefox is currently shutting down. We may prevent doing
    *        some cleanups to speed it up. Otherwise everything need to be
    *        cleaned up in order to be able to load devtools again.
    */
--- a/devtools/shim/DevToolsShim.jsm
+++ b/devtools/shim/DevToolsShim.jsm
@@ -172,16 +172,26 @@ this.DevToolsShim = {
    */
   restoreScratchpadSession: function (scratchpads) {
     if (!this.isInstalled()) {
       return;
     }
     this.gDevTools.restoreScratchpadSession(scratchpads);
   },
 
+  /*
+   * Compatibility layer for toolkit/mozapps/extensions/internal/XPIProvider.jsm.
+   */
+  isToolboxProcessLoaded: function () {
+    if (!this.isInstalled()) {
+      return false;
+    }
+    return this.gDevTools.isToolboxProcessLoaded();
+  },
+
   _onDevToolsRegistered: function () {
     // Register all pending event listeners on the real gDevTools object.
     for (let [event, listener] of this.listeners) {
       this.gDevTools.on(event, listener);
     }
 
     for (let tool of this.tools) {
       this.gDevTools.registerTool(tool);
@@ -219,17 +229,29 @@ let addonSdkMethods = [
  *
  * Those methods are called only after a DevTools webextension was loaded in DevTools,
  * therefore DevTools should always be available when they are called.
  */
 let webExtensionsMethods = [
   "getTheme",
 ];
 
-for (let method of [...addonSdkMethods, ...webExtensionsMethods]) {
+/**
+ * Compatibility layer for toolkit/mozapps/extensions/internal/XPIProvider.jsm.
+ *
+ * XPIProvider needs to interact with the BrowserToolboxProcess. This could probably be
+ * simplified, using events to communicate between the BrowserToolboxProcess and the
+ * XPIProvider.
+ */
+let XPIProviderMethods = [
+  "getBrowserToolboxProcess"
+];
+
+let methods = [...addonSdkMethods, ...webExtensionsMethods, ...XPIProviderMethods];
+for (let method of methods) {
   this.DevToolsShim[method] = function () {
     if (!this.isInstalled()) {
       throw new Error(`Method ${method} unavailable if DevTools are not installed`);
     }
 
     return this.gDevTools[method].apply(this.gDevTools, arguments);
   };
 }
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -37,18 +37,20 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PermissionsUtils",
                                   "resource://gre/modules/PermissionsUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "BrowserToolboxProcess",
-                                  "resource://devtools/client/framework/ToolboxProcess.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "DevToolsShim",
+                                  "chrome://devtools-shim/content/DevToolsShim.jsm");
+XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess",
+                                  () => DevToolsShim.getBrowserToolboxProcess());
 XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPI",
                                   "resource://gre/modules/Console.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ProductAddonChecker",
                                   "resource://gre/modules/addons/ProductAddonChecker.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
                                   "resource://gre/modules/UpdateUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
                                   "resource://gre/modules/AppConstants.jsm");
@@ -2219,29 +2221,31 @@ this.XPIProvider = {
       Services.prefs.addObserver(PREF_E10S_ADDON_BLOCKLIST, this);
       Services.prefs.addObserver(PREF_E10S_ADDON_POLICY, this);
       if (!AppConstants.MOZ_REQUIRE_SIGNING || Cu.isInAutomation)
         Services.prefs.addObserver(PREF_XPI_SIGNATURES_REQUIRED, this);
       Services.prefs.addObserver(PREF_ALLOW_LEGACY, this);
       Services.prefs.addObserver(PREF_ALLOW_NON_MPC, this);
       Services.obs.addObserver(this, NOTIFICATION_FLUSH_PERMISSIONS);
 
-      // Cu.isModuleLoaded can fail here for external XUL apps where there is
-      // no chrome.manifest that defines resource://devtools.
-      if (ResProtocolHandler.hasSubstitution("devtools")) {
-        if (Cu.isModuleLoaded("resource://devtools/client/framework/ToolboxProcess.jsm")) {
+      try {
+        if (DevToolsShim.isToolboxProcessLoaded()) {
           // If BrowserToolboxProcess is already loaded, set the boolean to true
           // and do whatever is needed
           this._toolboxProcessLoaded = true;
+
           BrowserToolboxProcess.on("connectionchange",
                                    this.onDebugConnectionChange.bind(this));
         } else {
           // Else, wait for it to load
           Services.obs.addObserver(this, NOTIFICATION_TOOLBOXPROCESS_LOADED);
         }
+      } catch (e) {
+        // Accessing DevToolsShim could crash for XUL apps which don't build devtools at
+        // all.
       }
 
 
       let flushCaches = this.checkForChanges(aAppChanged, aOldAppVersion,
                                              aOldPlatformVersion);
 
       // Changes to installed extensions may have changed which theme is selected
       this.applyThemeChange();