diff --git a/devtools/client/framework/test/browser_tab_descriptor_fission.js b/devtools/client/framework/test/browser_tab_descriptor_fission.js
index b9b93b329708..c88c58e49f5e 100644
--- a/devtools/client/framework/test/browser_tab_descriptor_fission.js
+++ b/devtools/client/framework/test/browser_tab_descriptor_fission.js
@@ -26,15 +26,6 @@ add_task(async function() {
);
ok(tabDescriptor, "Should have a descriptor actor for the tab");
- const firstCommands = await tabDescriptor.getCommands();
- ok(firstCommands, "Got commands");
- const secondCommands = await tabDescriptor.getCommands();
- is(
- firstCommands,
- secondCommands,
- "Multiple calls to getCommands return the same commands object"
- );
-
is(
target.descriptorFront,
tabDescriptor,
diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js
index 4799ac17e36b..69ad42530209 100644
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -39,6 +39,7 @@ var Startup = Cc["@mozilla.org/devtools/startup-clh;1"].getService(
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
+const { createCommandsDictionary } = require("devtools/shared/commands/index");
const { BrowserLoader } = ChromeUtils.import(
"resource://devtools/client/shared/browser-loader.js"
@@ -778,7 +779,8 @@ Toolbox.prototype = {
// It exposes commands modules listed in devtools/shared/commands/index.js
// which are an abstraction on top of RDP methods.
// See devtools/shared/commands/README.md
- this.commands = await this.descriptorFront.getCommands();
+ // Bug 1700909 will make the commands be instantiated by gDevTools instead of the Toolbox.
+ this.commands = await createCommandsDictionary(this.descriptorFront);
//TODO: complete the renaming of targetList everywhere
// But for now, still expose this name on Toolbox
diff --git a/devtools/client/fronts/descriptors/descriptor-mixin.js b/devtools/client/fronts/descriptors/descriptor-mixin.js
index 8128192600ee..26af5d8a42d3 100644
--- a/devtools/client/fronts/descriptors/descriptor-mixin.js
+++ b/devtools/client/fronts/descriptors/descriptor-mixin.js
@@ -4,8 +4,6 @@
"use strict";
-const { createCommandsDictionary } = require("devtools/shared/commands/index");
-
/**
* A Descriptor represents a debuggable context. It can be a browser tab, a tab on
* a remote device, like a tab on Firefox for Android. But it can also be an add-on,
@@ -33,13 +31,6 @@ function DescriptorMixin(parentClass) {
get client() {
return this._client;
}
-
- async getCommands() {
- if (!this._commands) {
- this._commands = createCommandsDictionary(this);
- }
- return this._commands;
- }
}
return Descriptor;
}
diff --git a/devtools/client/responsive/test/browser/head.js b/devtools/client/responsive/test/browser/head.js
index 1c55b89fbc09..619a14049734 100644
--- a/devtools/client/responsive/test/browser/head.js
+++ b/devtools/client/responsive/test/browser/head.js
@@ -626,7 +626,7 @@ function addDeviceForTest(device) {
async function waitForClientClose(ui) {
info("Waiting for RDM devtools client to close");
- await ui.client.once("closed");
+ await ui.commands.client.once("closed");
info("RDM's devtools client is now closed");
}
diff --git a/devtools/client/responsive/ui.js b/devtools/client/responsive/ui.js
index fb1852762592..10d977dd5d48 100644
--- a/devtools/client/responsive/ui.js
+++ b/devtools/client/responsive/ui.js
@@ -14,19 +14,10 @@ const Constants = require("devtools/client/responsive/constants");
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
+const {
+ CommandsFactory,
+} = require("devtools/shared/commands/commands-factory");
-loader.lazyRequireGetter(
- this,
- "DevToolsClient",
- "devtools/client/devtools-client",
- true
-);
-loader.lazyRequireGetter(
- this,
- "DevToolsServer",
- "devtools/server/devtools-server",
- true
-);
loader.lazyRequireGetter(
this,
"throttlingProfiles",
@@ -364,34 +355,22 @@ class ResponsiveUI {
this.resizeHandleY = null;
this.resizeToolbarObserver = null;
- // Close the devtools client used to speak with responsive emulation actor.
+ // Destroying the commands will close the devtools client used to speak with responsive emulation actor.
// The actor handles clearing any overrides itself, so it's not necessary to clear
// anything on shutdown client side.
- const clientClosed = this.client.close();
+ const commandsDestroyed = this.commands.destroy();
if (!isTabContentDestroying) {
- await clientClosed;
+ await commandsDestroyed;
}
- this.client = this.responsiveFront = null;
+ this.commands = this.responsiveFront = null;
this.destroyed = true;
return true;
}
async connectToServer() {
- // The client being instantiated here is separate from the toolbox. It is being used
- // separately and has a life cycle that doesn't correspond to the toolbox.
- DevToolsServer.init();
- DevToolsServer.registerAllActors();
- this.client = new DevToolsClient(DevToolsServer.connectPipe());
- await this.client.connect();
-
- // Pass a proper `tab` filter option to getTab in order to create a
- // "local" TabDescriptor, which handles target switching autonomously with
- // its corresponding target-list.
- const descriptor = await this.client.mainRoot.getTab({ tab: this.tab });
-
- const commands = await descriptor.getCommands();
- this.targetList = commands.targetCommand;
+ this.commands = await CommandsFactory.forTab(this.tab);
+ this.targetList = this.commands.targetCommand;
this.resourceWatcher = new ResourceWatcher(this.targetList);
await this.targetList.startListening();
diff --git a/devtools/client/shared/test/shared-head.js b/devtools/client/shared/test/shared-head.js
index 14027621c653..7ca284e44ecf 100644
--- a/devtools/client/shared/test/shared-head.js
+++ b/devtools/client/shared/test/shared-head.js
@@ -51,6 +51,9 @@ const { gDevTools } = require("devtools/client/framework/devtools");
const {
TabDescriptorFactory,
} = require("devtools/client/framework/tab-descriptor-factory");
+const {
+ CommandsFactory,
+} = require("devtools/shared/commands/commands-factory");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
// This is overridden in files that load shared-head via loadSubScript.
@@ -534,8 +537,13 @@ async function navigateTo(uri, { isErrorPage = false } = {}) {
async function createAndAttachTargetForTab(tab) {
info("Creating and attaching to a local tab target");
- const descriptor = await TabDescriptorFactory.createDescriptorForTab(tab);
- const target = await descriptor.getTarget();
+ const commands = await CommandsFactory.forTab(tab);
+
+ // Initialize the TargetCommands which require some async stuff to be done
+ // before being fully ready. This will define the `targetCommand.targetFront` attribute.
+ await commands.targetCommand.startListening();
+
+ const target = commands.targetCommand.targetFront;
await target.attach();
return target;
}
diff --git a/devtools/client/webconsole/browser-console-manager.js b/devtools/client/webconsole/browser-console-manager.js
index 138158f61bdf..7aa9b573dcd9 100644
--- a/devtools/client/webconsole/browser-console-manager.js
+++ b/devtools/client/webconsole/browser-console-manager.js
@@ -5,18 +5,11 @@
"use strict";
var Services = require("Services");
-const ChromeUtils = require("ChromeUtils");
-const { DevToolsLoader } = ChromeUtils.import(
- "resource://devtools/shared/Loader.jsm"
-);
+const {
+ CommandsFactory,
+} = require("devtools/shared/commands/commands-factory");
loader.lazyRequireGetter(this, "Tools", "devtools/client/definitions", true);
-loader.lazyRequireGetter(
- this,
- "DevToolsClient",
- "devtools/client/devtools-client",
- true
-);
loader.lazyRequireGetter(this, "l10n", "devtools/client/webconsole/utils/l10n");
loader.lazyRequireGetter(
this,
@@ -38,7 +31,6 @@ class BrowserConsoleManager {
this._browserConsole = null;
this._browserConsoleInitializing = null;
this._browerConsoleSessionState = false;
- this._devToolsClient = null;
}
storeBrowserConsoleSessionState() {
@@ -50,17 +42,15 @@ class BrowserConsoleManager {
}
/**
- * Open a Browser Console for the given commands context.
+ * Open a Browser Console for the current commands context.
*
- * @param object commands
- * The commands object with all interfaces defined from devtools/shared/commands/
* @param nsIDOMWindow iframeWindow
* The window where the browser console UI is already loaded.
* @return object
* A promise object for the opening of the new BrowserConsole instance.
*/
- async openBrowserConsole(commands, win) {
- const hud = new BrowserConsole(commands, win, win);
+ async openBrowserConsole(win) {
+ const hud = new BrowserConsole(this.commands, win, win);
this._browserConsole = hud;
await hud.init();
return hud;
@@ -77,8 +67,8 @@ class BrowserConsoleManager {
await this._browserConsole.destroy();
this._browserConsole = null;
- await this._devToolsClient.close();
- this._devToolsClient = null;
+ await this.commands.destroy();
+ this.commands = null;
}
/**
@@ -96,9 +86,9 @@ class BrowserConsoleManager {
// Temporarily cache the async startup sequence so that if toggleBrowserConsole
// gets called again we can return this console instead of opening another one.
this._browserConsoleInitializing = (async () => {
- const commands = await this.connect();
+ this.commands = await CommandsFactory.forBrowserConsole();
const win = await this.openWindow();
- const browserConsole = await this.openBrowserConsole(commands, win);
+ const browserConsole = await this.openBrowserConsole(win);
return browserConsole;
})();
@@ -107,51 +97,6 @@ class BrowserConsoleManager {
return browserConsole;
}
- /**
- * One method to handle the whole setup sequence to connect to RDP backend.
- *
- * This will instantiate a special DevTools module loader for the DevToolsServer.
- * Then spawn a DevToolsClient to connect to it.
- * Get a Main Process Descriptor from it.
- * Finally spawn a commands object for this descriptor.
- */
- async connect() {
- // The Browser console ends up using the debugger in autocomplete.
- // Because the debugger can't be running in the same compartment than its debuggee,
- // we have to load the server in a dedicated Loader, flagged with
- // `freshCompartment`, which will force it to be loaded in another compartment.
- // We aren't using `invisibleToDebugger` in order to allow the Browser toolbox to
- // debug the Browser console. This is fine as they will spawn distinct Loaders and
- // so distinct `DevToolsServer` and actor modules.
- const loader = new DevToolsLoader({
- freshCompartment: true,
- });
- const { DevToolsServer } = loader.require(
- "devtools/server/devtools-server"
- );
-
- DevToolsServer.init();
-
- // We want all the actors (root, browser and target-scoped) to be registered on the
- // DevToolsServer. This is needed so the Browser Console can retrieve:
- // - the console actors, which are target-scoped (See Bug 1416105)
- // - the screenshotActor, which is browser-scoped (for the `:screenshot` command)
- DevToolsServer.registerAllActors();
-
- DevToolsServer.allowChromeProcess = true;
-
- this._devToolsClient = new DevToolsClient(DevToolsServer.connectPipe());
- await this._devToolsClient.connect();
-
- const descriptor = await this._devToolsClient.mainRoot.getMainProcess();
-
- // Hack something in order to help TargetMixinFront to distinguish the BrowserConsole
- descriptor.createdForBrowserConsole = true;
-
- const commands = await descriptor.getCommands();
- return commands;
- }
-
async openWindow() {
const win = Services.ww.openWindow(
null,
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js
index a150ce17bc9b..c15c0547ba21 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js
@@ -5,7 +5,8 @@
const {
STUBS_UPDATE_ENV,
- createResourceWatcherForTab,
+ createCommandsForTab,
+ createResourceWatcherForCommands,
getStubFile,
getCleanedPacket,
getSerializedPacket,
@@ -55,15 +56,14 @@ add_task(async function() {
} else {
ok(true, "Stubs are up to date");
}
-
- await closeTabAndToolbox().catch(() => {});
});
async function generateConsoleApiStubs() {
const stubs = new Map();
const tab = await addTab(TEST_URI);
- const resourceWatcher = await createResourceWatcherForTab(tab);
+ const commands = await createCommandsForTab(tab);
+ const resourceWatcher = await createResourceWatcherForCommands(commands);
// The resource-watcher only supports a single call to watch/unwatch per
// instance, so we attach a unique watch callback, which will forward the
@@ -115,6 +115,8 @@ async function generateConsoleApiStubs() {
onAvailable: onConsoleMessage,
});
+ await commands.destroy();
+
return stubs;
}
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_css_message.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_css_message.js
index c5119502802e..c85ed900e8f4 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_css_message.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_css_message.js
@@ -5,7 +5,8 @@
const {
STUBS_UPDATE_ENV,
- createResourceWatcherForTab,
+ createCommandsForTab,
+ createResourceWatcherForCommands,
getCleanedPacket,
getStubFile,
writeStubsToFile,
@@ -61,7 +62,8 @@ async function generateCssMessageStubs() {
const stubs = new Map();
const tab = await addTab(TEST_URI);
- const resourceWatcher = await createResourceWatcherForTab(tab);
+ const commands = await createCommandsForTab(tab);
+ const resourceWatcher = await createResourceWatcherForCommands(commands);
// The resource-watcher only supports a single call to watch/unwatch per
// instance, so we attach a unique watch callback, which will forward the
@@ -103,7 +105,7 @@ async function generateCssMessageStubs() {
onAvailable: onCSSMessageAvailable,
});
- await closeTabAndToolbox().catch(() => {});
+ await commands.destroy();
return stubs;
}
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_network_event.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_network_event.js
index 8eeea50d23a3..aed3b64ce8aa 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_network_event.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_network_event.js
@@ -4,7 +4,8 @@
"use strict";
const {
- createResourceWatcherForTab,
+ createCommandsForTab,
+ createResourceWatcherForCommands,
STUBS_UPDATE_ENV,
getStubFile,
getCleanedPacket,
@@ -57,7 +58,8 @@ add_task(async function() {
async function generateNetworkEventStubs() {
const stubs = new Map();
const tab = await addTab(TEST_URI);
- const resourceWatcher = await createResourceWatcherForTab(tab);
+ const commands = await createCommandsForTab(tab);
+ const resourceWatcher = await createResourceWatcherForCommands(commands);
const stacktraces = new Map();
let addNetworkStub = function() {};
let addNetworkUpdateStub = function() {};
@@ -145,6 +147,9 @@ async function generateNetworkEventStubs() {
onUpdated,
}
);
+
+ await commands.destroy();
+
return stubs;
}
// Ensures the order of the resource properties
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js
index 6b13a9c5eba2..2e61097ba1ae 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js
@@ -5,7 +5,8 @@
const {
STUBS_UPDATE_ENV,
- createResourceWatcherForTab,
+ createCommandsForTab,
+ createResourceWatcherForCommands,
getCleanedPacket,
getSerializedPacket,
getStubFile,
@@ -57,15 +58,14 @@ add_task(async function() {
} else {
ok(true, "Stubs are up to date");
}
-
- await closeTabAndToolbox();
});
async function generatePageErrorStubs() {
const stubs = new Map();
const tab = await addTab(TEST_URI);
- const resourceWatcher = await createResourceWatcherForTab(tab);
+ const commands = await createCommandsForTab(tab);
+ const resourceWatcher = await createResourceWatcherForCommands(commands);
// The resource-watcher only supports a single call to watch/unwatch per
// instance, so we attach a unique watch callback, which will forward the
diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_platform_messages.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_platform_messages.js
index ae9a0a510f62..53f218898081 100644
--- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_platform_messages.js
+++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_platform_messages.js
@@ -5,7 +5,8 @@
const {
STUBS_UPDATE_ENV,
- createResourceWatcherForDescriptor,
+ createCommandsForMainProcess,
+ createResourceWatcherForCommands,
getCleanedPacket,
getSerializedPacket,
getStubFile,
@@ -59,22 +60,8 @@ add_task(async function() {
async function generatePlatformMessagesStubs() {
const stubs = new Map();
- // Instantiate a minimal server
- const { DevToolsClient } = require("devtools/client/devtools-client");
- const { DevToolsServer } = require("devtools/server/devtools-server");
- DevToolsServer.init();
- DevToolsServer.allowChromeProcess = true;
- if (!DevToolsServer.createRootActor) {
- DevToolsServer.registerAllActors();
- }
- const transport = DevToolsServer.connectPipe();
- const client = new DevToolsClient(transport);
- await client.connect();
- const mainProcessDescriptor = await client.mainRoot.getMainProcess();
-
- const resourceWatcher = await createResourceWatcherForDescriptor(
- mainProcessDescriptor
- );
+ const commands = await createCommandsForMainProcess();
+ const resourceWatcher = await createResourceWatcherForCommands(commands);
// The resource-watcher only supports a single call to watch/unwatch per
// instance, so we attach a unique watch callback, which will forward the
@@ -105,7 +92,7 @@ async function generatePlatformMessagesStubs() {
}
resourceWatcher.targetList.destroy();
- await client.close();
+ await commands.destroy();
return stubs;
}
diff --git a/devtools/client/webconsole/test/browser/stub-generator-helpers.js b/devtools/client/webconsole/test/browser/stub-generator-helpers.js
index 10edfc1bf219..477f7e73d93a 100644
--- a/devtools/client/webconsole/test/browser/stub-generator-helpers.js
+++ b/devtools/client/webconsole/test/browser/stub-generator-helpers.js
@@ -14,25 +14,28 @@ const CHROME_PREFIX = "chrome://mochitests/content/browser/";
const STUBS_FOLDER = "devtools/client/webconsole/test/node/fixtures/stubs/";
const STUBS_UPDATE_ENV = "WEBCONSOLE_STUBS_UPDATE";
-async function createResourceWatcherForTab(tab) {
+async function createCommandsForTab(tab) {
const {
- TabDescriptorFactory,
- } = require("devtools/client/framework/tab-descriptor-factory");
- const descriptor = await TabDescriptorFactory.createDescriptorForTab(tab);
- const target = await descriptor.getTarget();
- const resourceWatcher = await createResourceWatcherForDescriptor(
- target.descriptorFront
- );
- return resourceWatcher;
+ CommandsFactory,
+ } = require("devtools/shared/commands/commands-factory");
+ const commands = await CommandsFactory.forTab(tab);
+ return commands;
}
-async function createResourceWatcherForDescriptor(descriptor) {
+async function createCommandsForMainProcess() {
+ const {
+ CommandsFactory,
+ } = require("devtools/shared/commands/commands-factory");
+ const commands = await CommandsFactory.forMainProcess();
+ return commands;
+}
+
+async function createResourceWatcherForCommands(commands) {
// Avoid mocha to try to load these module and fail while doing it when running node tests
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
- const commands = await descriptor.getCommands();
const targetList = commands.targetCommand;
await targetList.startListening();
return new ResourceWatcher(targetList);
@@ -542,8 +545,9 @@ function parsePacketAndCreateFronts(packet) {
module.exports = {
STUBS_UPDATE_ENV,
- createResourceWatcherForTab,
- createResourceWatcherForDescriptor,
+ createCommandsForTab,
+ createCommandsForMainProcess,
+ createResourceWatcherForCommands,
getStubFile,
getCleanedPacket,
getSerializedPacket,
diff --git a/devtools/server/connectors/content-process-connector.js b/devtools/server/connectors/content-process-connector.js
index 7c5c0de0e116..4f159acc3526 100644
--- a/devtools/server/connectors/content-process-connector.js
+++ b/devtools/server/connectors/content-process-connector.js
@@ -104,7 +104,11 @@ function connectToContentProcess(connection, mm, onDestroy) {
if (subject == mm) {
// Send the "tabDetached" event before closing the connection which
// will destroy fronts on the client.
- connection.send({ from: actor.actor, type: "tabDetached" });
+ // Note that the content process may be destroyed before the actor is created.
+ // Avoid trying to send any tabDetached in such situation.
+ if (actor) {
+ connection.send({ from: actor.actor, type: "tabDetached" });
+ }
onClose();
}
}
diff --git a/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js b/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js
index 2047add8905c..3ba196a9e111 100644
--- a/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js
+++ b/devtools/server/tests/browser/browser_stylesheets_getTextEmpty.js
@@ -11,15 +11,17 @@ const TEST_URI = `data:text/html;charset=utf-8,`;
add_task(async function() {
- const target = await addTabTarget(TEST_URI);
+ const browser = await addTab(TEST_URI);
+ const tab = gBrowser.getTabForBrowser(browser);
const {
ResourceWatcher,
} = require("devtools/shared/resources/resource-watcher");
- const commands = await target.descriptorFront.getCommands();
+ const commands = await CommandsFactory.forTab(tab);
const targetList = commands.targetCommand;
await targetList.startListening();
+ const target = targetList.targetFront;
const resourceWatcher = new ResourceWatcher(targetList);
const styleSheetsFront = await target.getFront("stylesheets");
diff --git a/devtools/server/tests/browser/browser_watcher-watchTargets-frames.js b/devtools/server/tests/browser/browser_watcher-watchTargets-frames.js
index 1e7f502f2cc8..c7e968e1306a 100644
--- a/devtools/server/tests/browser/browser_watcher-watchTargets-frames.js
+++ b/devtools/server/tests/browser/browser_watcher-watchTargets-frames.js
@@ -8,6 +8,9 @@
"use strict";
const TEST_DOC_URL = MAIN_DOMAIN + "doc_iframe.html";
+const {
+ createLocalClientForTests,
+} = require("devtools/shared/commands/commands-factory");
// URL of the