tor-browser

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

MessageManager.webidl (19049B)


      1 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 interface nsIEventTarget;
      7 interface Principal;
      8 
      9 /**
     10 * Message managers provide a way for chrome-privileged JS code to
     11 * communicate with each other, even across process boundaries.
     12 *
     13 * Message managers are separated into "parent side" and "child side".
     14 * These don't always correspond to process boundaries, but can.  For
     15 * each child-side message manager, there is always exactly one
     16 * corresponding parent-side message manager that it sends messages
     17 * to.  However, for each parent-side message manager, there may be
     18 * either one or many child-side managers it can message.
     19 *
     20 * Message managers that always have exactly one "other side" are of
     21 * type MessageSender.  Parent-side message managers that have many
     22 * "other sides" are of type MessageBroadcaster.
     23 *
     24 * Child-side message managers can send synchronous messages to their
     25 * parent side, but not the other way around.
     26 *
     27 * There are two realms of message manager hierarchies.  One realm
     28 * approximately corresponds to DOM elements, the other corresponds to
     29 * process boundaries.
     30 *
     31 * Message managers corresponding to DOM elements
     32 * ==============================================
     33 *
     34 * In this realm of message managers, there are
     35 *  - "frame message managers" which correspond to frame elements
     36 *  - "window message managers" which correspond to top-level chrome
     37 *    windows
     38 *  - "group message managers" which correspond to named message
     39 *    managers with a specific window MM as the parent
     40 *  - the "global message manager", on the parent side.  See below.
     41 *
     42 * The DOM-realm message managers can communicate in the ways shown by
     43 * the following diagram.  The parent side and child side can
     44 * correspond to process boundaries, but don't always.
     45 *
     46 *  Parent side                         Child side
     47 * -------------                       ------------
     48 *  global MMg
     49 *   |
     50 *   +-->window MMw1
     51 *   |    |
     52 *   |    +-->frame MMp1_1<------------>frame MMc1_1
     53 *   |    |
     54 *   |    +-->frame MMp1_2<------------>frame MMc1_2
     55 *   |    |
     56 *   |    +-->group MMgr1
     57 *   |    |    |
     58 *   |    |    +-->frame MMp2_1<------->frame MMc2_1
     59 *   |    |    |
     60 *   |    |    +-->frame MMp2_2<------->frame MMc2_2
     61 *   |    |
     62 *   |    +-->group MMgr2
     63 *   |    |    ...
     64 *   |    |
     65 *   |    ...
     66 *   |
     67 *   +-->window MMw2
     68 *   ...
     69 *
     70 * For example: a message sent from MMc1_1, from the child side, is
     71 * sent only to MMp1_1 on the parent side.  However, note that all
     72 * message managers in the hierarchy above MMp1_1, in this diagram
     73 * MMw1 and MMg, will also notify their message listeners when the
     74 * message arrives.
     75 *
     76 * A message sent from MMc2_1 will be sent to MMp2_1 and also notify
     77 * all message managers in the hierarchy above that, including the
     78 * group message manager MMgr1.
     79 
     80 * For example: a message broadcast through the global MMg on the
     81 * parent side would be broadcast to MMw1, which would transitively
     82 * broadcast it to MMp1_1, MM1p_2.  The message would next be
     83 * broadcast to MMgr1, which would broadcast it to MMp2_1 and MMp2_2.
     84 * After that it would broadcast to MMgr2 and then to MMw2, and so
     85 * on down the hierarchy.
     86 *
     87 *   ***** PERFORMANCE AND SECURITY WARNING *****
     88 * Messages broadcast through the global MM and window or group MMs
     89 * can result in messages being dispatched across many OS processes,
     90 * and to many processes with different permissions.  Great care
     91 * should be taken when broadcasting.
     92 *
     93 * Interfaces
     94 * ----------
     95 *
     96 * The global MMg and window MMw's are message broadcasters implementing
     97 * MessageBroadcaster while the frame MMp's are simple message senders (MessageSender).
     98 * Their counterparts in the content processes are message senders implementing
     99 * ContentFrameMessageManager.
    100 *
    101 *                 MessageListenerManager
    102 *               /                        \
    103 * MessageSender                            MessageBroadcaster
    104 *       |
    105 * SyncMessageSender (content process/in-process only)
    106 *       |
    107 * ContentFrameMessageManager (content process/in-process only)
    108 *       |
    109 * nsIInProcessContentFrameMessageManager (in-process only)
    110 *
    111 *
    112 * Message managers in the chrome process also implement FrameScriptLoader.
    113 *
    114 *
    115 * Message managers corresponding to process boundaries
    116 * ====================================================
    117 *
    118 * The second realm of message managers is the "process message
    119 * managers".  With one exception, these always correspond to process
    120 * boundaries.  The picture looks like
    121 *
    122 *  Parent process                      Child processes
    123 * ----------------                    -----------------
    124 *  global (GPPMM)
    125 *   |
    126 *   +-->parent in-process PIPMM<-->child in-process CIPPMM
    127 *   |
    128 *   +-->parent (PPMM1)<------------------>child (CPMM1)
    129 *   |
    130 *   +-->parent (PPMM2)<------------------>child (CPMM2)
    131 *   ...
    132 *
    133 * Note, PIPMM and CIPPMM both run in the parent process.
    134 *
    135 * For example: the parent-process PPMM1 sends messages to the
    136 * child-process CPMM1.
    137 *
    138 * For example: CPMM1 sends messages directly to PPMM1. The global GPPMM
    139 * will also notify their message listeners when the message arrives.
    140 *
    141 * For example: messages sent through the global GPPMM will be
    142 * dispatched to the listeners of the same-process, CIPPMM, CPMM1,
    143 * CPMM2, etc.
    144 *
    145 *   ***** PERFORMANCE AND SECURITY WARNING *****
    146 * Messages broadcast through the GPPMM can result in messages
    147 * being dispatched across many OS processes, and to many processes
    148 * with different permissions.  Great care should be taken when
    149 * broadcasting.
    150 *
    151 * Requests sent to parent-process message listeners should usually
    152 * have replies scoped to the requesting CPMM.  The following pattern
    153 * is common
    154 *
    155 *  const ParentProcessListener = {
    156 *    receiveMessage: function(aMessage) {
    157 *      switch (aMessage.name) {
    158 *      case "Foo:Request":
    159 *        // service request
    160 *        aMessage.target.sendAsyncMessage("Foo:Response", { data });
    161 *      }
    162 *    }
    163 *  };
    164 */
    165 
    166 dictionary ReceiveMessageArgument
    167 {
    168  /**
    169   * The target of the message. Either an element owning the message manager, or message
    170   * manager itself if no element owns it.
    171   */
    172  required nsISupports target;
    173 
    174  /**
    175   * Message name.
    176   */
    177  required DOMString name;
    178 
    179  required boolean sync;
    180 
    181  /**
    182   * Structured clone of the sent message data
    183   */
    184  any data = null;
    185 
    186  /**
    187   * Same as .data, deprecated.
    188   */
    189  any json = null;
    190 
    191  sequence<MessagePort> ports;
    192 
    193  FrameLoader targetFrameLoader;
    194 };
    195 
    196 [Exposed=Window]
    197 callback interface MessageListener
    198 {
    199  /**
    200   * Each listener is invoked with its own copy of the message
    201   * parameter.
    202   *
    203   * When the listener is called, 'this' value is the target of the message.
    204   *
    205   * If the message is synchronous, the possible return value is
    206   * returned as JSON (will be changed to use structured clones).
    207   * When there are multiple listeners to sync messages, each
    208   * listener's return value is sent back as an array.  |undefined|
    209   * return values show up as undefined values in the array.
    210   */
    211  any receiveMessage(ReceiveMessageArgument argument);
    212 };
    213 
    214 [ChromeOnly, Exposed=Window]
    215 interface MessageListenerManager
    216 {
    217  // All the methods are pulled in via mixin.
    218 };
    219 MessageListenerManager includes MessageListenerManagerMixin;
    220 
    221 interface mixin MessageListenerManagerMixin
    222 {
    223  /**
    224   * Register |listener| to receive |messageName|.  All listener
    225   * callbacks for a particular message are invoked when that message
    226   * is received.
    227   *
    228   * The message manager holds a strong ref to |listener|.
    229   *
    230   * If the same listener registers twice for the same message, the
    231   * second registration is ignored.
    232   *
    233   * Pass true for listenWhenClosed if you want to receive messages
    234   * during the short period after a frame has been removed from the
    235   * DOM and before its frame script has finished unloading. This
    236   * parameter only has an effect for frame message managers in
    237   * the main process. Default is false.
    238   */
    239  [Throws]
    240  undefined addMessageListener(DOMString messageName,
    241                               MessageListener listener,
    242                               optional boolean listenWhenClosed = false);
    243 
    244  /**
    245   * Undo an |addMessageListener| call -- that is, calling this causes us to no
    246   * longer invoke |listener| when |messageName| is received.
    247   *
    248   * removeMessageListener does not remove a message listener added via
    249   * addWeakMessageListener; use removeWeakMessageListener for that.
    250   */
    251  [Throws]
    252  undefined removeMessageListener(DOMString messageName,
    253                                  MessageListener listener);
    254 
    255  /**
    256   * This is just like addMessageListener, except the message manager holds a
    257   * weak ref to |listener|.
    258   *
    259   * If you have two weak message listeners for the same message, they may be
    260   * called in any order.
    261   */
    262  [Throws]
    263  undefined addWeakMessageListener(DOMString messageName,
    264                                   MessageListener listener);
    265 
    266  /**
    267   * This undoes an |addWeakMessageListener| call.
    268   */
    269  [Throws]
    270  undefined removeWeakMessageListener(DOMString messageName,
    271                                      MessageListener listener);
    272 };
    273 
    274 /**
    275 * Message "senders" have a single "other side" to which messages are
    276 * sent.  For example, a child-process message manager will send
    277 * messages that are only delivered to its one parent-process message
    278 * manager.
    279 */
    280 [ChromeOnly, Exposed=Window]
    281 interface MessageSender : MessageListenerManager
    282 {
    283  // All the methods are pulled in via mixin.
    284 };
    285 MessageSender includes MessageSenderMixin;
    286 
    287 /**
    288 * Anyone including this MUST also incude MessageListenerManagerMixin.
    289 */
    290 interface mixin MessageSenderMixin {
    291  /**
    292   * Send |messageName| and |obj| to the "other side" of this message
    293   * manager.  This invokes listeners who registered for
    294   * |messageName|.
    295   *
    296   * See ReceiveMessageArgument for the format of the data delivered to listeners.
    297   * @throws NS_ERROR_NOT_INITIALIZED if the sender is not initialized.  For
    298   *         example, we will throw NS_ERROR_NOT_INITIALIZED if we try to send
    299   *         a message to a cross-process frame but the other process has not
    300   *         yet been set up.
    301   * @throws NS_ERROR_FAILURE when the message receiver cannot be found.  For
    302   *         example, we will throw NS_ERROR_FAILURE if we try to send a message
    303   *         to a cross-process frame whose process has crashed.
    304   */
    305  [Throws]
    306  undefined sendAsyncMessage(optional DOMString? messageName = null,
    307                             optional any obj,
    308                             optional any transfers);
    309 
    310  /**
    311   * For remote browsers there is always a corresponding process message
    312   * manager. The intention of this attribute is to link leaf level frame
    313   * message managers on the parent side with the corresponding process
    314   * message managers (if there is one). For any other cases this property
    315   * is null.
    316   */
    317  [Throws]
    318  readonly attribute MessageSender? processMessageManager;
    319 
    320  /**
    321   * For remote browsers, this contains the remoteType of the content child.
    322   * Otherwise, it is empty.
    323   */
    324  [Throws]
    325  readonly attribute UTF8String remoteType;
    326 };
    327 
    328 [ChromeOnly, Exposed=Window]
    329 interface SyncMessageSender : MessageSender
    330 {
    331  // All the methods are pulled in via mixin.
    332 };
    333 SyncMessageSender includes SyncMessageSenderMixin;
    334 
    335 /**
    336 * Anyone including this MUST also incude MessageSenderMixin.
    337 */
    338 interface mixin SyncMessageSenderMixin
    339 {
    340  /**
    341   * Like |sendAsyncMessage()|, except blocks the sender until all
    342   * listeners of the message have been invoked.  Returns an array
    343   * containing return values from each listener invoked.
    344   */
    345  [Throws]
    346  sequence<any> sendSyncMessage(optional DOMString? messageName = null,
    347                                optional any obj);
    348 };
    349 
    350 /**
    351 * ChildProcessMessageManager is used in a child process to communicate with the parent
    352 * process.
    353 */
    354 [ChromeOnly, Exposed=Window]
    355 interface ChildProcessMessageManager : SyncMessageSender
    356 {
    357 };
    358 
    359 /**
    360 * Mixin for message manager globals.  Anyone including this MUST also
    361 * include SyncMessageSenderMixin.
    362 */
    363 interface mixin MessageManagerGlobal
    364 {
    365  /**
    366   * Print a string to stdout.
    367   */
    368  undefined dump(DOMString str);
    369 
    370  /**
    371   * Ascii base64 data to binary data and vice versa
    372   */
    373  [Throws]
    374  DOMString atob(DOMString asciiString);
    375  [Throws]
    376  DOMString btoa(DOMString base64Data);
    377 };
    378 
    379 interface mixin FrameScriptLoader
    380 {
    381  /**
    382   * Load a script in the (remote) frame. |url| must be the absolute URL.
    383   * data: URLs are also supported. For example data:,dump("foo\n");
    384   * If allowDelayedLoad is true, script will be loaded when the
    385   * remote frame becomes available. Otherwise the script will be loaded
    386   * only if the frame is already available.
    387   */
    388  [Throws]
    389  undefined loadFrameScript(DOMString url, boolean allowDelayedLoad,
    390                            optional boolean runInGlobalScope = false);
    391 
    392  /**
    393   * Removes |url| from the list of scripts which support delayed load.
    394   */
    395  undefined removeDelayedFrameScript(DOMString url);
    396 
    397  /**
    398   * Returns all delayed scripts that will be loaded once a (remote)
    399   * frame becomes available. The return value is a list of pairs
    400   * [<URL>, <WasLoadedInGlobalScope>].
    401   */
    402  [Throws]
    403  sequence<sequence<any>> getDelayedFrameScripts();
    404 };
    405 
    406 interface mixin ProcessScriptLoader
    407 {
    408  /**
    409   * Load a script in the (possibly remote) process. |url| must be the absolute
    410   * URL. data: URLs are also supported. For example data:,dump("foo\n");
    411   * If allowDelayedLoad is true, script will be loaded when the
    412   * remote frame becomes available. Otherwise the script will be loaded
    413   * only if the frame is already available.
    414   */
    415  [Throws]
    416  undefined loadProcessScript(DOMString url, boolean allowDelayedLoad);
    417 
    418  /**
    419   * Removes |url| from the list of scripts which support delayed load.
    420   */
    421  undefined removeDelayedProcessScript(DOMString url);
    422 
    423  /**
    424   * Returns all delayed scripts that will be loaded once a (remote)
    425   * frame becomes available. The return value is a list of pairs
    426   * [<URL>, <WasLoadedInGlobalScope>].
    427   */
    428  [Throws]
    429  sequence<sequence<any>> getDelayedProcessScripts();
    430 };
    431 
    432 /**
    433 * Anyone including GlobalProcessScriptLoader MUST also include ProcessScriptLoader.
    434 */
    435 interface mixin GlobalProcessScriptLoader
    436 {
    437  /**
    438   * Allows the parent process to set the initial process data for
    439   * new, not-yet-created child processes. This attribute should only
    440   * be used by the global parent process message manager. When a new
    441   * process is created, it gets a copy of this data (via structured
    442   * cloning). It can access the data via the initialProcessData
    443   * attribute of its childprocessmessagemanager.
    444   *
    445   * This value will always be a JS object if it's not null or undefined. Different
    446   * users are expected to set properties on this object. The property name should be
    447   * unique enough that other Gecko consumers won't accidentally choose it.
    448   */
    449  [Throws]
    450  readonly attribute any initialProcessData;
    451 
    452  readonly attribute MozWritableSharedMap sharedData;
    453 };
    454 
    455 [ChromeOnly, Exposed=Window]
    456 interface ContentFrameMessageManager : EventTarget
    457 {
    458  /**
    459   * The current top level window in the frame or null.
    460   */
    461  [Throws]
    462  readonly attribute WindowProxy? content;
    463 
    464  /**
    465   * The top level docshell or null.
    466   */
    467  [Throws]
    468  readonly attribute nsIDocShell? docShell;
    469 
    470  /**
    471   * Returns the SchedulerEventTarget corresponding to the TabGroup
    472   * for this frame.
    473   */
    474  readonly attribute nsIEventTarget? tabEventTarget;
    475 
    476 };
    477 ContentFrameMessageManager includes MessageManagerGlobal;
    478 ContentFrameMessageManager includes SyncMessageSenderMixin;
    479 ContentFrameMessageManager includes MessageSenderMixin;
    480 ContentFrameMessageManager includes MessageListenerManagerMixin;
    481 
    482 [ChromeOnly, Exposed=Window]
    483 interface ContentProcessMessageManager
    484 {
    485  /**
    486   * Read out a copy of the object that was initialized in the parent
    487   * process via ProcessScriptLoader.initialProcessData.
    488   */
    489  [Throws]
    490  readonly attribute any initialProcessData;
    491 
    492  readonly attribute MozSharedMap? sharedData;
    493 };
    494 ContentProcessMessageManager includes MessageManagerGlobal;
    495 ContentProcessMessageManager includes SyncMessageSenderMixin;
    496 ContentProcessMessageManager includes MessageSenderMixin;
    497 ContentProcessMessageManager includes MessageListenerManagerMixin;
    498 
    499 /**
    500 * Message "broadcasters" don't have a single "other side" that they send messages to, but
    501 * rather a set of subordinate message managers. For example, broadcasting a message
    502 * through a window message manager will broadcast the message to all frame message
    503 * managers within its window.
    504 */
    505 [ChromeOnly, Exposed=Window]
    506 interface MessageBroadcaster : MessageListenerManager
    507 {
    508  /**
    509   * Like |sendAsyncMessage()|, but also broadcasts this message to
    510   * all "child" message managers of this message manager.  See long
    511   * comment above for details.
    512   *
    513   * WARNING: broadcasting messages can be very expensive and leak
    514   * sensitive data.  Use with extreme caution.
    515   */
    516  [Throws]
    517  undefined broadcastAsyncMessage(optional DOMString? messageName = null,
    518                                  optional any obj);
    519 
    520  /**
    521   * Number of subordinate message managers.
    522   */
    523  readonly attribute unsigned long childCount;
    524 
    525  /**
    526   * Return a single subordinate message manager.
    527   */
    528  MessageListenerManager? getChildAt(unsigned long aIndex);
    529 
    530  /**
    531   * Some processes are kept alive after their last tab/window are closed for testing
    532   * (see dom.ipc.keepProcessesAlive). This function releases those.
    533   */
    534   undefined releaseCachedProcesses();
    535 };
    536 
    537 /**
    538 * ChromeMessageBroadcaster is used for window and group message managers.
    539 */
    540 [ChromeOnly, Exposed=Window]
    541 interface ChromeMessageBroadcaster : MessageBroadcaster
    542 {
    543 };
    544 ChromeMessageBroadcaster includes FrameScriptLoader;
    545 
    546 /**
    547 * ParentProcessMessageManager is used in a parent process to communicate with all the
    548 * child processes.
    549 */
    550 [ChromeOnly, Exposed=Window]
    551 interface ParentProcessMessageManager : MessageBroadcaster
    552 {
    553 };
    554 ParentProcessMessageManager includes ProcessScriptLoader;
    555 ParentProcessMessageManager includes GlobalProcessScriptLoader;
    556 
    557 [ChromeOnly, Exposed=Window]
    558 interface ChromeMessageSender : MessageSender
    559 {
    560 };
    561 ChromeMessageSender includes FrameScriptLoader;
    562 
    563 /**
    564 * ProcessMessageManager is used in a parent process to communicate with a child process
    565 * (or with the process itself in a single-process scenario).
    566 */
    567 [ChromeOnly, Exposed=Window]
    568 interface ProcessMessageManager : MessageSender
    569 {
    570  // PID of the process being communicated with.
    571  readonly attribute long osPid;
    572 
    573  // Whether this is message manager for the current process.
    574  readonly attribute boolean isInProcess;
    575 };
    576 ProcessMessageManager includes ProcessScriptLoader;