diff options
Diffstat (limited to '')
-rw-r--r-- | devtools/server/startup/content-process.sys.mjs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/devtools/server/startup/content-process.sys.mjs b/devtools/server/startup/content-process.sys.mjs new file mode 100644 index 0000000000..fd974e8c4a --- /dev/null +++ b/devtools/server/startup/content-process.sys.mjs @@ -0,0 +1,104 @@ +/* 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/. */ + +/* + * Module that listens for requests to start a `DevToolsServer` for an entire content + * process. Loaded into content processes by the main process during + * content-process-connector.js' `connectToContentProcess` via the process + * script `content-process.js`. + * + * The actual server startup itself is in this JSM so that code can be cached. + */ + +export function initContentProcessTarget(msg) { + const mm = msg.target; + const prefix = msg.data.prefix; + const watcherActorID = msg.data.watcherActorID; + + // Lazy load Loader.sys.mjs to prevent loading any devtools dependency too early. + const { + useDistinctSystemPrincipalLoader, + releaseDistinctSystemPrincipalLoader, + } = ChromeUtils.importESModule( + "resource://devtools/shared/loader/DistinctSystemPrincipalLoader.sys.mjs" + ); + + // Use a unique object to identify this one usage of the loader + const loaderRequester = {}; + + // Init a custom, invisible DevToolsServer, in order to not pollute the + // debugger with all devtools modules, nor break the debugger itself with + // using it in the same process. + const loader = useDistinctSystemPrincipalLoader(loaderRequester); + + const { DevToolsServer } = loader.require( + "resource://devtools/server/devtools-server.js" + ); + + DevToolsServer.init(); + // For browser content toolbox, we do need a regular root actor and all tab + // actors, but don't need all the "browser actors" that are only useful when + // debugging the parent process via the browser toolbox. + DevToolsServer.registerActors({ root: true, target: true }); + + // Connect both parent/child processes devtools servers RDP via message + // managers + const conn = DevToolsServer.connectToParent(prefix, mm); + + const { ContentProcessTargetActor } = loader.require( + "resource://devtools/server/actors/targets/content-process.js" + ); + + const actor = new ContentProcessTargetActor(conn, { + sessionContext: msg.data.sessionContext, + }); + actor.manage(actor); + + const response = { watcherActorID, prefix, actor: actor.form() }; + mm.sendAsyncMessage("debug:content-process-actor", response); + + function onDestroy(options) { + mm.removeMessageListener( + "debug:content-process-disconnect", + onContentProcessDisconnect + ); + actor.off("destroyed", onDestroy); + + // Notify the parent process that the actor is being destroyed + mm.sendAsyncMessage("debug:content-process-actor-destroyed", { + watcherActorID, + }); + + // Call DevToolsServerConnection.close to destroy all child actors. It should end up + // calling DevToolsServerConnection.onTransportClosed that would actually cleanup all actor + // pools. + conn.close(options); + + // Destroy the related loader when the target is destroyed + // and we were the last user of the special loader + releaseDistinctSystemPrincipalLoader(loaderRequester); + } + function onContentProcessDisconnect(message) { + if (message.data.prefix != prefix) { + // Several copies of this process script can be running for a single process if + // we are debugging the same process from multiple clients. + // If this disconnect request doesn't match a connection known here, ignore it. + return; + } + onDestroy(); + } + + // Clean up things when the client disconnects + mm.addMessageListener( + "debug:content-process-disconnect", + onContentProcessDisconnect + ); + // And also when the target actor is destroyed + actor.on("destroyed", onDestroy); + + return { + actor, + connection: conn, + }; +} |