tor-browser

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

content-process-connector.js (3953B)


      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 "use strict";
      6 
      7 var DevToolsUtils = require("resource://devtools/shared/DevToolsUtils.js");
      8 var { dumpn } = DevToolsUtils;
      9 var {
     10  createContentProcessSessionContext,
     11 } = require("resource://devtools/server/actors/watcher/session-context.js");
     12 
     13 loader.lazyRequireGetter(
     14  this,
     15  "ChildDebuggerTransport",
     16  "resource://devtools/shared/transport/child-transport.js",
     17  true
     18 );
     19 
     20 const CONTENT_PROCESS_SERVER_STARTUP_SCRIPT =
     21  "resource://devtools/server/startup/content-process.js";
     22 
     23 loader.lazyRequireGetter(
     24  this,
     25  "EventEmitter",
     26  "resource://devtools/shared/event-emitter.js"
     27 );
     28 
     29 /**
     30 * Start a DevTools server in a content process (representing the entire process, not
     31 * just a single frame) and add it as a child server for an active connection.
     32 */
     33 function connectToContentProcess(connection, mm, onDestroy) {
     34  return new Promise(resolve => {
     35    const prefix = connection.allocID("content-process");
     36    let actor, childTransport;
     37 
     38    mm.addMessageListener(
     39      "debug:content-process-actor",
     40      function listener(msg) {
     41        // Ignore actors being created by a Watcher actor,
     42        // they will be handled by devtools/server/watcher/target-helpers/process.js
     43        if (msg.watcherActorID) {
     44          return;
     45        }
     46        mm.removeMessageListener("debug:content-process-actor", listener);
     47 
     48        // Pipe Debugger message from/to parent/child via the message manager
     49        childTransport = new ChildDebuggerTransport(mm, prefix);
     50        childTransport.hooks = {
     51          onPacket: connection.send.bind(connection),
     52        };
     53        childTransport.ready();
     54 
     55        connection.setForwarding(prefix, childTransport);
     56 
     57        dumpn(`Start forwarding for process with prefix ${prefix}`);
     58 
     59        actor = msg.json.actor;
     60 
     61        resolve(actor);
     62      }
     63    );
     64 
     65    // Load the content process server startup script only once.
     66    const isContentProcessServerStartupScripLoaded = Services.ppmm
     67      .getDelayedProcessScripts()
     68      .some(([uri]) => uri === CONTENT_PROCESS_SERVER_STARTUP_SCRIPT);
     69    if (!isContentProcessServerStartupScripLoaded) {
     70      // Load the process script that will receive the debug:init-content-server message
     71      Services.ppmm.loadProcessScript(
     72        CONTENT_PROCESS_SERVER_STARTUP_SCRIPT,
     73        true
     74      );
     75    }
     76 
     77    // Send a message to the content process server startup script to forward it the
     78    // prefix.
     79    mm.sendAsyncMessage("debug:init-content-server", {
     80      prefix,
     81      // This connector is only used for the Browser Content Toolbox,
     82      // when creating the content process target from the Process Descriptor.
     83      sessionContext: createContentProcessSessionContext(),
     84    });
     85 
     86    function onClose() {
     87      Services.obs.removeObserver(
     88        onMessageManagerClose,
     89        "message-manager-close"
     90      );
     91      connection.off("closed", onClose);
     92      if (childTransport) {
     93        // If we have a child transport, the actor has already
     94        // been created. We need to stop using this message manager.
     95        childTransport.close();
     96        childTransport = null;
     97        connection.cancelForwarding(prefix);
     98 
     99        // ... and notify the child process to clean the target-scoped actors.
    100        try {
    101          mm.sendAsyncMessage("debug:content-process-disconnect", { prefix });
    102        } catch (e) {
    103          // Nothing to do
    104        }
    105      }
    106 
    107      if (onDestroy) {
    108        onDestroy(mm);
    109      }
    110    }
    111 
    112    const onMessageManagerClose = DevToolsUtils.makeInfallible(subject => {
    113      if (subject == mm) {
    114        onClose();
    115      }
    116    });
    117    Services.obs.addObserver(onMessageManagerClose, "message-manager-close");
    118 
    119    connection.on("closed", onClose);
    120  });
    121 }
    122 
    123 exports.connectToContentProcess = connectToContentProcess;