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;