tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

content-process.sys.mjs (3745B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /*
      6 * Module that listens for requests to start a `DevToolsServer` for an entire content
      7 * process.  Loaded into content processes by the main process during
      8 * content-process-connector.js' `connectToContentProcess` via the process
      9 * script `content-process.js`.
     10 *
     11 * The actual server startup itself is in this JSM so that code can be cached.
     12 */
     13 
     14 export function initContentProcessTarget(msg) {
     15  const mm = msg.target;
     16  const prefix = msg.data.prefix;
     17  const watcherActorID = msg.data.watcherActorID;
     18 
     19  // Lazy load Loader.sys.mjs to prevent loading any devtools dependency too early.
     20  const {
     21    useDistinctSystemPrincipalLoader,
     22    releaseDistinctSystemPrincipalLoader,
     23  } = ChromeUtils.importESModule(
     24    "resource://devtools/shared/loader/DistinctSystemPrincipalLoader.sys.mjs",
     25    { global: "shared" }
     26  );
     27 
     28  // Use a unique object to identify this one usage of the loader
     29  const loaderRequester = {};
     30 
     31  // Init a custom, invisible DevToolsServer, in order to not pollute the
     32  // debugger with all devtools modules, nor break the debugger itself with
     33  // using it in the same process.
     34  const loader = useDistinctSystemPrincipalLoader(loaderRequester);
     35 
     36  const { DevToolsServer } = loader.require(
     37    "resource://devtools/server/devtools-server.js"
     38  );
     39 
     40  DevToolsServer.init();
     41  // For browser content toolbox, we do need a regular root actor and all tab
     42  // actors, but don't need all the "browser actors" that are only useful when
     43  // debugging the parent process via the browser toolbox.
     44  DevToolsServer.registerActors({ root: true, target: true });
     45 
     46  // Connect both parent/child processes devtools servers RDP via message
     47  // managers
     48  const conn = DevToolsServer.connectToParent(prefix, mm);
     49 
     50  const { ContentProcessTargetActor } = loader.require(
     51    "resource://devtools/server/actors/targets/content-process.js"
     52  );
     53 
     54  const actor = new ContentProcessTargetActor(conn, {
     55    sessionContext: msg.data.sessionContext,
     56  });
     57  actor.manage(actor);
     58 
     59  const response = { watcherActorID, prefix, actor: actor.form() };
     60  mm.sendAsyncMessage("debug:content-process-actor", response);
     61 
     62  function onDestroy(options) {
     63    mm.removeMessageListener(
     64      "debug:content-process-disconnect",
     65      onContentProcessDisconnect
     66    );
     67    actor.off("destroyed", onDestroy);
     68 
     69    // Notify the parent process that the actor is being destroyed
     70    mm.sendAsyncMessage("debug:content-process-actor-destroyed", {
     71      watcherActorID,
     72    });
     73 
     74    // Call DevToolsServerConnection.close to destroy all child actors. It should end up
     75    // calling DevToolsServerConnection.onTransportClosed that would actually cleanup all actor
     76    // pools.
     77    conn.close(options);
     78 
     79    // Destroy the related loader when the target is destroyed
     80    // and we were the last user of the special loader
     81    releaseDistinctSystemPrincipalLoader(loaderRequester);
     82  }
     83  function onContentProcessDisconnect(message) {
     84    if (message.data.prefix != prefix) {
     85      // Several copies of this process script can be running for a single process if
     86      // we are debugging the same process from multiple clients.
     87      // If this disconnect request doesn't match a connection known here, ignore it.
     88      return;
     89    }
     90    onDestroy();
     91  }
     92 
     93  // Clean up things when the client disconnects
     94  mm.addMessageListener(
     95    "debug:content-process-disconnect",
     96    onContentProcessDisconnect
     97  );
     98  // And also when the target actor is destroyed
     99  actor.on("destroyed", onDestroy);
    100 
    101  return {
    102    actor,
    103    connection: conn,
    104  };
    105 }