forked from mirrors/gecko-dev
174 lines
6.3 KiB
JavaScript
174 lines
6.3 KiB
JavaScript
/* 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";
|
|
|
|
const { createCommandsDictionary } = require("devtools/shared/commands/index");
|
|
const ChromeUtils = require("ChromeUtils");
|
|
const { DevToolsLoader } = ChromeUtils.import(
|
|
"resource://devtools/shared/Loader.jsm"
|
|
);
|
|
loader.lazyRequireGetter(
|
|
this,
|
|
"DevToolsServer",
|
|
"devtools/server/devtools-server",
|
|
true
|
|
);
|
|
// eslint-disable-next-line mozilla/reject-some-requires
|
|
loader.lazyRequireGetter(
|
|
this,
|
|
"DevToolsClient",
|
|
"devtools/client/devtools-client",
|
|
true
|
|
);
|
|
|
|
/**
|
|
* Functions for creating Commands for all debuggable contexts.
|
|
*
|
|
* All methods of this `CommandsFactory` object receive argument to describe to
|
|
* which particular context we want to debug. And all returns a new instance of `commands` object.
|
|
* Commands are implemented by modules defined in devtools/shared/commands.
|
|
*/
|
|
exports.CommandsFactory = {
|
|
async forTab(tab) {
|
|
const client = await createLocalClient();
|
|
|
|
const descriptor = await client.mainRoot.getTab({ tab });
|
|
const commands = await createCommandsDictionary(descriptor);
|
|
return commands;
|
|
},
|
|
|
|
async forMainProcess() {
|
|
const client = await createLocalClient();
|
|
|
|
const descriptor = await client.mainRoot.getMainProcess();
|
|
const commands = await createCommandsDictionary(descriptor);
|
|
return commands;
|
|
},
|
|
|
|
/**
|
|
* For now, this method is only used by browser_target_list_various_descriptors.js
|
|
* in order to cover about:debugging codepath, where we connect to remote tabs via
|
|
* their current outerWindowID.
|
|
* But:
|
|
* 1) this can also be used to debug local tab, but TabDescriptor.localTab/isLocalTab will be null/false.
|
|
* 2) beyond this test, this isn't used to connect to remote tab just yet.
|
|
* Bug 1700909 should start using this from toolbox-init/descriptor-from-url
|
|
* and will finaly be used to connect to remote tabs.
|
|
*/
|
|
async forRemoteTabInTest({ outerWindowID }) {
|
|
const client = await createLocalClient();
|
|
|
|
const descriptor = await client.mainRoot.getTab({ outerWindowID });
|
|
const commands = await createCommandsDictionary(descriptor);
|
|
return commands;
|
|
},
|
|
|
|
/**
|
|
* `id` is the WorkerDebugger's id, which is a unique ID computed by the platform code.
|
|
* These ids are exposed via WorkerDescriptor's id attributes.
|
|
* WorkerDescritpors can be retrieved via MainFront.listAllWorkers()/listWorkers().
|
|
*/
|
|
async forWorker(id) {
|
|
const client = await createLocalClient();
|
|
|
|
const descriptor = await client.mainRoot.getWorker(id);
|
|
const commands = await createCommandsDictionary(descriptor);
|
|
return commands;
|
|
},
|
|
|
|
async forAddon(id) {
|
|
const client = await createLocalClient();
|
|
|
|
const descriptor = await client.mainRoot.getAddon({ id });
|
|
const commands = await createCommandsDictionary(descriptor);
|
|
return commands;
|
|
},
|
|
|
|
async forProcess(osPid) {
|
|
const client = await createLocalClient();
|
|
|
|
const descriptor = await client.mainRoot.getProcess(osPid);
|
|
const commands = await createCommandsDictionary(descriptor);
|
|
return commands;
|
|
},
|
|
|
|
/**
|
|
* One method to handle the whole setup sequence to connect to RDP backend for the Browser Console.
|
|
*
|
|
* 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 forBrowserConsole() {
|
|
// 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 customLoader = new DevToolsLoader({
|
|
freshCompartment: true,
|
|
});
|
|
const { DevToolsServer: customDevToolsServer } = customLoader.require(
|
|
"devtools/server/devtools-server"
|
|
);
|
|
|
|
customDevToolsServer.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)
|
|
customDevToolsServer.registerAllActors();
|
|
|
|
customDevToolsServer.allowChromeProcess = true;
|
|
|
|
const client = new DevToolsClient(customDevToolsServer.connectPipe());
|
|
await client.connect();
|
|
|
|
const descriptor = await client.mainRoot.getMainProcess();
|
|
|
|
// Hack something in order to help TargetMixinFront to distinguish the BrowserConsole
|
|
descriptor.createdForBrowserConsole = true;
|
|
|
|
const target = await descriptor.getTarget();
|
|
await target.attach();
|
|
|
|
const commands = await createCommandsDictionary(descriptor);
|
|
return commands;
|
|
},
|
|
};
|
|
|
|
async function createLocalClient() {
|
|
// Make sure the DevTools server is started.
|
|
ensureDevToolsServerInitialized();
|
|
|
|
// Create the client and connect it to the local server.
|
|
const client = new DevToolsClient(DevToolsServer.connectPipe());
|
|
await client.connect();
|
|
|
|
return client;
|
|
}
|
|
// Also expose this method for tests which would like to create a client
|
|
// without involving commands. This would typically be tests against the Watcher actor
|
|
// and requires to prevent having TargetCommand from running.
|
|
// Or tests which are covering RootFront or global actor's fronts.
|
|
exports.createLocalClientForTests = createLocalClient;
|
|
|
|
function ensureDevToolsServerInitialized() {
|
|
// Since a remote protocol connection will be made, let's start the
|
|
// DevToolsServer here, once and for all tools.
|
|
DevToolsServer.init();
|
|
|
|
// Enable all the actors. We may not need all of them and registering
|
|
// only root and target might be enough
|
|
DevToolsServer.registerAllActors();
|
|
|
|
// Enable being able to get child process actors
|
|
// Same, this might not be useful
|
|
DevToolsServer.allowChromeProcess = true;
|
|
}
|