Bug 1536888 - Move the remote agent to a JSM. r=ato
authorAlexandre Poirot <poirot.alex@gmail.com>
Fri, 22 Mar 2019 09:46:50 +0000
changeset 527502 232833b7f5bbe68f65dcea0fb3168ef859018b9a
parent 527501 046333a3b9ebd3e9566ad1c75146ac5f1f8cb96a
child 527503 0a6867082f4e8d348f9659a98162591a1bdab49c
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersato
bugs1536888, 1536862
milestone68.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 1536888 - Move the remote agent to a JSM. r=ato This will later help register the component statically in bug 1536862. And already ease using the remote agent from other JSM files. Differential Revision: https://phabricator.services.mozilla.com/D24227
remote/RemoteAgent.js
remote/RemoteAgent.jsm
remote/RemoteAgent.manifest
remote/command-line-handler.js
remote/jar.mn
remote/moz.build
remote/targets/MainProcessTarget.jsm
remote/targets/TabTarget.jsm
remote/test/browser/browser_cdp.js
remote/test/browser/browser_tabs.js
remote/test/browser/browser_target.js
rename from remote/RemoteAgent.js
rename to remote/RemoteAgent.jsm
--- a/remote/RemoteAgent.js
+++ b/remote/RemoteAgent.jsm
@@ -1,14 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+var EXPORTED_SYMBOLS = ["RemoteAgent"];
+
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   FatalError: "chrome://remote/content/Error.jsm",
   HttpServer: "chrome://remote/content/server/HTTPD.jsm",
   JSONHandler: "chrome://remote/content/JSONHandler.jsm",
   Log: "chrome://remote/content/Log.jsm",
@@ -23,18 +25,25 @@ XPCOMUtils.defineLazyGetter(this, "log",
 
 const ENABLED = "remote.enabled";
 const FORCE_LOCAL = "remote.force-local";
 
 const DEFAULT_HOST = "localhost";
 const DEFAULT_PORT = 9222;
 const LOOPBACKS = ["localhost", "127.0.0.1", "[::1]"];
 
-class ParentRemoteAgent {
-  constructor() {
+class RemoteAgentClass {
+  init() {
+    if (!Preferences.get(ENABLED, false)) {
+      throw new Error("Remote agent is disabled by its preference");
+    }
+    if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
+      throw new Error("Remote agent can only be instantiated from the parent process");
+    }
+
     this.server = new HttpServer();
     this.targets = new Targets();
 
     this.server.registerPrefixHandler("/json/", new JSONHandler(this));
 
     this.tabs = new TabObserver({registerExisting: true});
     this.tabs.on("open", (eventName, tab) => {
       this.targets.connect(tab.linkedBrowser);
@@ -47,20 +56,16 @@ class ParentRemoteAgent {
       if (!target.path) {
         throw new Error(`Target is missing 'path' attribute: ${target}`);
       }
       this.server.registerPathHandler(target.path, target);
     });
     this.targets.on("disconnect", (eventName, target) => {
       // TODO(ato): removing a handler is currently not possible
     });
-
-    // This allows getting access to the underlying JS object
-    // of the @mozilla.org/remote/agent XPCOM components
-    this.wrappedJSObject = this;
   }
 
   get listening() {
     return !!this.server && !this.server._socketClosed;
   }
 
   listen(address) {
     if (!(address instanceof Ci.nsIURI)) {
@@ -168,16 +173,18 @@ class ParentRemoteAgent {
     try {
       addr = NetUtil.newURI(`http://${host || DEFAULT_HOST}:${port || DEFAULT_PORT}/`);
     } catch (e) {
       log.fatal(`Expected address syntax [<host>]:<port>: ${remoteDebugger || remoteDebuggingPort}`);
       cmdLine.preventDefault = true;
       return;
     }
 
+    this.init();
+
     await Observer.once("sessionstore-windows-restored");
     await this.tabs.start();
 
     try {
       this.listen(addr);
     } catch (e) {
       this.close();
       throw new FatalError(`Unable to start remote agent on ${addr.spec}: ${e.message}`, e);
@@ -193,40 +200,9 @@ class ParentRemoteAgent {
 
   // XPCOM
 
   get QueryInterface() {
     return ChromeUtils.generateQI([Ci.nsICommandLineHandler]);
   }
 }
 
-const RemoteAgentFactory = {
-  instance_: null,
-
-  createInstance(outer, iid) {
-    if (outer) {
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    }
-    if (!Preferences.get(ENABLED, false)) {
-      return null;
-    }
-
-    if (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT) {
-      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-    }
-
-    if (!this.instance_) {
-      this.instance_ = new ParentRemoteAgent();
-    }
-    return this.instance_.QueryInterface(iid);
-  },
-};
-
-function RemoteAgent() {}
-
-RemoteAgent.prototype = {
-    classDescription: "Remote Agent",
-    classID: Components.ID("{8f685a9d-8181-46d6-a71d-869289099c6d}"),
-    contractID: "@mozilla.org/remote/agent",
-    _xpcom_factory: RemoteAgentFactory,  /* eslint-disable-line */
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RemoteAgent]);
+var RemoteAgent = new RemoteAgentClass();
--- a/remote/RemoteAgent.manifest
+++ b/remote/RemoteAgent.manifest
@@ -1,3 +1,3 @@
-component {8f685a9d-8181-46d6-a71d-869289099c6d} RemoteAgent.js
+component {8f685a9d-8181-46d6-a71d-869289099c6d} command-line-handler.js
 contract @mozilla.org/remote/agent {8f685a9d-8181-46d6-a71d-869289099c6d}
 category command-line-handler m-remote @mozilla.org/remote/agent
new file mode 100644
--- /dev/null
+++ b/remote/command-line-handler.js
@@ -0,0 +1,31 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+// Stopgap module until we can land bug 1536862 and remove this temporary file
+
+const {RemoteAgent} = ChromeUtils.import("chrome://remote/content/RemoteAgent.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const RemoteAgentFactory = {
+  createInstance(outer, iid) {
+    if (outer) {
+      throw Cr.NS_ERROR_NO_AGGREGATION;
+    }
+
+    return RemoteAgent.QueryInterface(iid);
+  },
+};
+
+function RemoteAgentComponent() {}
+
+RemoteAgentComponent.prototype = {
+    classDescription: "Remote Agent",
+    classID: Components.ID("{8f685a9d-8181-46d6-a71d-869289099c6d}"),
+    contractID: "@mozilla.org/remote/agent",
+    _xpcom_factory: RemoteAgentFactory,  /* eslint-disable-line */
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RemoteAgentComponent]);
--- a/remote/jar.mn
+++ b/remote/jar.mn
@@ -1,14 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 remote.jar:
 % content remote %content/
+  content/RemoteAgent.jsm (RemoteAgent.jsm)
+
   content/Connection.jsm (Connection.jsm)
   content/Error.jsm (Error.jsm)
   content/JSONHandler.jsm (JSONHandler.jsm)
   content/Log.jsm (Log.jsm)
   content/Observer.jsm (Observer.jsm)
   content/Protocol.jsm (Protocol.jsm)
   content/RecommendedPreferences.jsm (RecommendedPreferences.jsm)
   content/Sync.jsm (Sync.jsm)
--- a/remote/moz.build
+++ b/remote/moz.build
@@ -3,17 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += [
   "pref",
   "test",
 ]
 
 EXTRA_COMPONENTS += [
-    "RemoteAgent.js",
+    "command-line-handler.js",
     "RemoteAgent.manifest",
 ]
 
 JAR_MANIFESTS += ["jar.mn"]
 
 with Files("**"):
     BUG_COMPONENT = ("Remote Protocol", "Agent")
 with Files("targets/**"):
--- a/remote/targets/MainProcessTarget.jsm
+++ b/remote/targets/MainProcessTarget.jsm
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["MainProcessTarget"];
 
 const {Target} = ChromeUtils.import("chrome://remote/content/targets/Target.jsm");
 const {Session} = ChromeUtils.import("chrome://remote/content/sessions/Session.jsm");
+const {RemoteAgent} = ChromeUtils.import("chrome://remote/content/RemoteAgent.jsm");
 
 /**
  * The main process Target.
  *
  * Matches BrowserDevToolsAgentHost from chromium, and only support a couple of Domains:
  * https://cs.chromium.org/chromium/src/content/browser/devtools/browser_devtools_agent_host.cc?dr=CSs&g=0&l=80-91
  */
 class MainProcessTarget extends Target {
@@ -24,18 +25,16 @@ class MainProcessTarget extends Target {
 
     this.type = "main-process";
 
     // Define the HTTP path to query this target
     this.path = "/devtools/browser";
   }
 
   get wsDebuggerURL() {
-    const RemoteAgent = Cc["@mozilla.org/remote/agent"]
-        .getService(Ci.nsISupports).wrappedJSObject;
     const {host, port} = RemoteAgent;
     return `ws://${host}:${port}${this.path}`;
   }
 
   toString() {
     return `[object MainProcessTarget]`;
   }
 
--- a/remote/targets/TabTarget.jsm
+++ b/remote/targets/TabTarget.jsm
@@ -5,16 +5,17 @@
 "use strict";
 
 var EXPORTED_SYMBOLS = ["TabTarget"];
 
 const {Target} = ChromeUtils.import("chrome://remote/content/targets/Target.jsm");
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {TabSession} = ChromeUtils.import("chrome://remote/content/sessions/TabSession.jsm");
 const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {RemoteAgent} = ChromeUtils.import("chrome://remote/content/RemoteAgent.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "Favicons",
     "@mozilla.org/browser/favicon-service;1", "nsIFaviconService");
 
 /**
  * Target for a local tab or a remoted frame.
  */
 class TabTarget extends Target {
@@ -96,18 +97,16 @@ class TabTarget extends Target {
     return "page";
   }
 
   get url() {
     return this.browser.currentURI.spec;
   }
 
   get wsDebuggerURL() {
-    const RemoteAgent = Cc["@mozilla.org/remote/agent"]
-        .getService(Ci.nsISupports).wrappedJSObject;
     const {host, port} = RemoteAgent;
     return `ws://${host}:${port}${this.path}`;
   }
 
   toString() {
     return `[object Target ${this.id}]`;
   }
 
--- a/remote/test/browser/browser_cdp.js
+++ b/remote/test/browser/browser_cdp.js
@@ -1,15 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 /* global getCDP */
 
+const {RemoteAgent} = ChromeUtils.import("chrome://remote/content/RemoteAgent.jsm");
+
 // Test very basic CDP features.
 
 const TEST_URI = "data:text/html;charset=utf-8,default-test-page";
 
 add_task(async function() {
   try {
     await testCDP();
   } catch (e) {
@@ -23,17 +25,17 @@ add_task(async function() {
   }
 });
 
 async function testCDP() {
   // Open a test page, to prevent debugging the random default page
   const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URI);
 
   // Start the CDP server
-  const RemoteAgent = Cc["@mozilla.org/remote/agent"].getService(Ci.nsISupports).wrappedJSObject;
+  RemoteAgent.init();
   RemoteAgent.tabs.start();
   RemoteAgent.listen(Services.io.newURI("http://localhost:9222"));
 
   // Retrieve the chrome-remote-interface library object
   const CDP = await getCDP();
 
   // Connect to the server
   const client = await CDP({
--- a/remote/test/browser/browser_tabs.js
+++ b/remote/test/browser/browser_tabs.js
@@ -1,20 +1,22 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Test very basic CDP features.
 
+const {RemoteAgent} = ChromeUtils.import("chrome://remote/content/RemoteAgent.jsm");
+
 const TEST_URI = "data:text/html;charset=utf-8,default-test-page";
 
 add_task(async function() {
   // Start the CDP server
-  const RemoteAgent = Cc["@mozilla.org/remote/agent"].getService(Ci.nsISupports).wrappedJSObject;
+  RemoteAgent.init();
   RemoteAgent.tabs.start();
   RemoteAgent.listen(Services.io.newURI("http://localhost:9222"));
 
   const CDP = await getCDP();
 
   // Use gBrowser.addTab instead of BrowserTestUtils as it creates the tab differently.
   // It demonstrates a race around tab.linkedBrowser.browsingContext being undefined
   // when accessing this property early.
--- a/remote/test/browser/browser_target.js
+++ b/remote/test/browser/browser_target.js
@@ -1,15 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 /* global getCDP */
 
+const {RemoteAgent} = ChromeUtils.import("chrome://remote/content/RemoteAgent.jsm");
+
 // Test the Target domain
 
 add_task(async function() {
   try {
     await testCDP();
   } catch (e) {
     // Display better error message with the server side stacktrace
     // if an error happened on the server side:
@@ -18,17 +20,17 @@ add_task(async function() {
     } else {
       throw e;
     }
   }
 });
 
 async function testCDP() {
   // Start the CDP server
-  const RemoteAgent = Cc["@mozilla.org/remote/agent"].getService(Ci.nsISupports).wrappedJSObject;
+  RemoteAgent.init();
   RemoteAgent.tabs.start();
   RemoteAgent.listen(Services.io.newURI("http://localhost:9222"));
 
   // Retrieve the chrome-remote-interface library object
   const CDP = await getCDP();
 
   // Connect to the server
   const {webSocketDebuggerUrl} = await CDP.Version();