tor-browser

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

MessageHandlerFrameChild.sys.mjs (3961B)


      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 const lazy = {};
      6 
      7 ChromeUtils.defineESModuleGetters(lazy, {
      8  isBrowsingContextCompatible:
      9    "chrome://remote/content/shared/messagehandler/transports/BrowsingContextUtils.sys.mjs",
     10  MessageHandlerRegistry:
     11    "chrome://remote/content/shared/messagehandler/MessageHandlerRegistry.sys.mjs",
     12  WindowGlobalMessageHandler:
     13    "chrome://remote/content/shared/messagehandler/WindowGlobalMessageHandler.sys.mjs",
     14 });
     15 
     16 /**
     17 * Map from MessageHandlerRegistry to MessageHandlerFrameChild actor. This will
     18 * allow a WindowGlobalMessageHandler to find the JSWindowActorChild instance to
     19 * use to send commands.
     20 */
     21 const registryToActor = new WeakMap();
     22 
     23 /**
     24 * Retrieve the MessageHandlerFrameChild which is linked to the provided
     25 * WindowGlobalMessageHandler instance.
     26 *
     27 * @param {WindowGlobalMessageHandler} messageHandler
     28 *     The WindowGlobalMessageHandler for which to get the JSWindowActor.
     29 * @returns {MessageHandlerFrameChild}
     30 *     The corresponding MessageHandlerFrameChild instance.
     31 */
     32 export function getMessageHandlerFrameChildActor(messageHandler) {
     33  return registryToActor.get(messageHandler.registry);
     34 }
     35 
     36 /**
     37 * Child actor for the MessageHandlerFrame JSWindowActor. The
     38 * MessageHandlerFrame actor is used by RootTransport to communicate between
     39 * ROOT MessageHandlers and WINDOW_GLOBAL MessageHandlers.
     40 */
     41 export class MessageHandlerFrameChild extends JSWindowActorChild {
     42  actorCreated() {
     43    this.type = lazy.WindowGlobalMessageHandler.type;
     44    this.context = this.manager.browsingContext;
     45 
     46    this._registry = new lazy.MessageHandlerRegistry(this.type, this.context);
     47    registryToActor.set(this._registry, this);
     48 
     49    this._onRegistryEvent = this._onRegistryEvent.bind(this);
     50 
     51    // MessageHandlerFrameChild is responsible for forwarding events from
     52    // WindowGlobalMessageHandler to the parent process.
     53    // Such events are re-emitted on the MessageHandlerRegistry to avoid
     54    // setting up listeners on individual MessageHandler instances.
     55    this._registry.on("message-handler-registry-event", this._onRegistryEvent);
     56  }
     57 
     58  handleEvent({ persisted, type }) {
     59    if (type == "DOMWindowCreated" || (type == "pageshow" && persisted)) {
     60      // When the window is created or is retrieved from BFCache, instantiate
     61      // a MessageHandler for all sessions which might need it.
     62      if (lazy.isBrowsingContextCompatible(this.manager.browsingContext)) {
     63        this._registry.createAllMessageHandlers();
     64      }
     65    } else if (type == "pagehide" && persisted) {
     66      // When the page is moved to BFCache, all the currently created message
     67      // handlers should be destroyed.
     68      this._registry.destroy();
     69    }
     70  }
     71 
     72  async receiveMessage(message) {
     73    if (message.name === "MessageHandlerFrameParent:sendCommand") {
     74      const { sessionId, command } = message.data;
     75      const messageHandler =
     76        this._registry.getOrCreateMessageHandler(sessionId);
     77      try {
     78        return await messageHandler.handleCommand(command);
     79      } catch (e) {
     80        if (e?.isRemoteError) {
     81          return {
     82            error: e.toJSON(),
     83            isMessageHandlerError: e.isMessageHandlerError,
     84          };
     85        }
     86        throw e;
     87      }
     88    } else if (message.name === "MessageHandlerFrameParent:sendPing") {
     89      return true;
     90    }
     91 
     92    return null;
     93  }
     94 
     95  sendCommand(command, sessionId) {
     96    return this.sendQuery("MessageHandlerFrameChild:sendCommand", {
     97      command,
     98      sessionId,
     99    });
    100  }
    101 
    102  _onRegistryEvent(eventName, wrappedEvent) {
    103    this.sendAsyncMessage(
    104      "MessageHandlerFrameChild:messageHandlerEvent",
    105      wrappedEvent
    106    );
    107  }
    108 
    109  didDestroy() {
    110    this._registry.off("message-handler-registry-event", this._onRegistryEvent);
    111    this._registry.destroy();
    112  }
    113 }