Bug 1364075 - remove DevTools dependency in ContentProcessSingleton;r=ochameau
MozReview-Commit-ID: 38XKKM37jC5
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -852,16 +852,19 @@ var gDevToolsBrowser = exports.gDevTools
gDevToolsBrowser._pingTelemetry();
gDevToolsBrowser._telemetry = null;
for (let win of gDevToolsBrowser._trackedBrowserWindows) {
gDevToolsBrowser._forgetBrowserWindow(win);
}
+ // Remove scripts loaded in content process to support the Browser Content Toolbox.
+ DebuggerServer.removeContentServerScript();
+
gDevTools.destroy({ shuttingDown });
},
};
// Handle all already registered tools,
gDevTools.getToolDefinitionArray()
.forEach(def => gDevToolsBrowser._addToolToWindows(def));
// and the new ones.
new file mode 100644
--- /dev/null
+++ b/devtools/server/content-process-debugger-server.js
@@ -0,0 +1,26 @@
+/* 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/. */
+
+/* global addMessageListener, removeMessageListener */
+
+"use strict";
+
+const { utils: Cu } = Components;
+const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
+function onInit(message) {
+ // Only reply if we are in a real content process
+ if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
+ let {init} = Cu.import("resource://devtools/server/content-server.jsm", {});
+ init(message);
+ }
+}
+
+function onClose() {
+ removeMessageListener("debug:init-content-server", onInit);
+ removeMessageListener("debug:close-content-server", onClose);
+}
+
+addMessageListener("debug:init-content-server", onInit);
+addMessageListener("debug:close-content-server", onClose);
--- a/devtools/server/main.js
+++ b/devtools/server/main.js
@@ -64,16 +64,19 @@ if (isWorker) {
const VERBOSE_PREF = "devtools.debugger.log.verbose";
flags.wantLogging = Services.prefs.getBoolPref(LOG_PREF);
flags.wantVerbose =
Services.prefs.getPrefType(VERBOSE_PREF) !== Services.prefs.PREF_INVALID &&
Services.prefs.getBoolPref(VERBOSE_PREF);
}
+const CONTENT_PROCESS_DBG_SERVER_SCRIPT =
+ "resource://devtools/server/content-process-debugger-server.js";
+
function loadSubScript(url) {
try {
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
loader.loadSubScript(url, this);
} catch (e) {
let errorStr = "Error loading: " + url + ":\n" +
(e.fileName ? "at " + e.fileName + " : " + e.lineNumber + "\n" : "") +
@@ -144,16 +147,18 @@ function ModuleAPI() {
}
/** *
* Public API
*/
var DebuggerServer = {
_listeners: [],
_initialized: false,
+ // Flag to check if the content process debugger server script was already loaded.
+ _contentProcessScriptLoaded: false,
// Map of global actor names to actor constructors provided by extensions.
globalActorFactories: {},
// Map of tab actor names to actor constructors provided by extensions.
tabActorFactories: {},
LONG_STRING_LENGTH: 10000,
LONG_STRING_INITIAL_LENGTH: 1000,
LONG_STRING_READ_LENGTH: 65 * 1024,
@@ -750,17 +755,26 @@ var DebuggerServer = {
dumpn("establishing forwarding for process with prefix " + prefix);
actor = msg.json.actor;
deferred.resolve(actor);
});
- mm.sendAsyncMessage("DevTools:InitDebuggerServer", {
+ // Load the content process debugger server script only once.
+ if (!this._contentProcessScriptLoaded) {
+ // Load the process script that will receive the debug:init-content-server message
+ Services.ppmm.loadProcessScript(CONTENT_PROCESS_DBG_SERVER_SCRIPT, true);
+ this._contentProcessScriptLoaded = true;
+ }
+
+ // Send a message to the content process debugger server script to forward it the
+ // prefix.
+ mm.sendAsyncMessage("debug:init-content-server", {
prefix: prefix
});
function onClose() {
Services.obs.removeObserver(onMessageManagerClose, "message-manager-close");
events.off(connection, "closed", onClose);
if (childTransport) {
// If we have a child transport, the actor has already
@@ -1364,16 +1378,30 @@ var DebuggerServer = {
for (let connID of Object.getOwnPropertyNames(this._connections)) {
this._connections[connID].rootActor.removeActorByName(name);
}
}
}
},
/**
+ * Called when DevTools are unloaded to remove the contend process server script for the
+ * list of scripts loaded for each new content process. Will also remove message
+ * listeners from already loaded scripts.
+ */
+ removeContentServerScript() {
+ Services.ppmm.removeDelayedProcessScript(CONTENT_PROCESS_DBG_SERVER_SCRIPT);
+ try {
+ Services.ppmm.broadcastAsyncMessage("debug:close-content-server");
+ } catch (e) {
+ // Nothing to do
+ }
+ },
+
+ /**
* ⚠ TESTING ONLY! ⚠ Searches all active connections for an actor matching an ID.
* This is helpful for some tests which depend on reaching into the server to check some
* properties of an actor.
*/
_searchAllConnectionsForActor(actorID) {
for (let connID of Object.getOwnPropertyNames(this._connections)) {
let actor = this._connections[connID].getActor(actorID);
if (actor) {
--- a/devtools/server/moz.build
+++ b/devtools/server/moz.build
@@ -13,16 +13,17 @@ DIRS += [
]
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
DevToolsModules(
'child.js',
+ 'content-process-debugger-server.js',
'content-server.jsm',
'css-logic.js',
'event-parsers.js',
'main.js',
'primitive.js',
'service-worker-child.js',
'websocket-server.js',
'worker.js'
--- a/toolkit/components/processsingleton/ContentProcessSingleton.js
+++ b/toolkit/components/processsingleton/ContentProcessSingleton.js
@@ -44,17 +44,16 @@ ContentProcessSingleton.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
observe(subject, topic, data) {
switch (topic) {
case "app-startup": {
Services.obs.addObserver(this, "console-api-log-event");
Services.obs.addObserver(this, "xpcom-shutdown");
- cpmm.addMessageListener("DevTools:InitDebuggerServer", this);
TelemetryController.observe(null, topic, null);
break;
}
case "console-api-log-event": {
let consoleMsg = subject.wrappedJSObject;
let msgData = {
level: consoleMsg.level,
@@ -98,24 +97,14 @@ ContentProcessSingleton.prototype = {
cpmm.sendAsyncMessage("Console:Log", msgData);
break;
}
case "xpcom-shutdown":
Services.obs.removeObserver(this, "console-api-log-event");
Services.obs.removeObserver(this, "xpcom-shutdown");
- cpmm.removeMessageListener("DevTools:InitDebuggerServer", this);
break;
}
},
-
- receiveMessage(message) {
- // load devtools component on-demand
- // Only reply if we are in a real content process
- if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
- let {init} = Cu.import("resource://devtools/server/content-server.jsm", {});
- init(message);
- }
- },
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentProcessSingleton]);