Bumping gaia.json for 8 gaia revision(s) a=gaia-bump
[gecko.git] / dom / base / nsIMessageManager.idl
blob3c7b44187b20360a43106069578ed4475d38e48f
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/. */
6 #include "nsISupports.idl"
8 interface nsIDOMWindow;
9 interface nsIDocShell;
10 interface nsIContent;
11 interface nsIPrincipal;
13 /**
14 * Message managers provide a way for chrome-privileged JS code to
15 * communicate with each other, even across process boundaries.
17 * Message managers are separated into "parent side" and "child side".
18 * These don't always correspond to process boundaries, but can. For
19 * each child-side message manager, there is always exactly one
20 * corresponding parent-side message manager that it sends messages
21 * to. However, for each parent-side message manager, there may be
22 * either one or many child-side managers it can message.
24 * Message managers that always have exactly one "other side" are of
25 * type nsIMessageSender. Parent-side message managers that have many
26 * "other sides" are of type nsIMessageBroadcaster.
28 * Child-side message managers can send synchronous messages to their
29 * parent side, but not the other way around.
31 * There are two realms of message manager hierarchies. One realm
32 * approximately corresponds to DOM elements, the other corresponds to
33 * process boundaries.
35 * Message managers corresponding to DOM elements
36 * ==============================================
38 * In this realm of message managers, there are
39 * - "frame message managers" which correspond to frame elements
40 * - "window message managers" which correspond to top-level chrome
41 * windows
42 * - "group message managers" which correspond to named message
43 * managers with a specific window MM as the parent
44 * - the "global message manager", on the parent side. See below.
46 * The DOM-realm message managers can communicate in the ways shown by
47 * the following diagram. The parent side and child side can
48 * correspond to process boundaries, but don't always.
50 * Parent side Child side
51 * ------------- ------------
52 * global MMg
53 * |
54 * +-->window MMw1
55 * | |
56 * | +-->frame MMp1_1<------------>frame MMc1_1
57 * | |
58 * | +-->frame MMp1_2<------------>frame MMc1_2
59 * | |
60 * | +-->group MMgr1
61 * | | |
62 * | | +-->frame MMp2_1<------->frame MMc2_1
63 * | | |
64 * | | +-->frame MMp2_2<------->frame MMc2_2
65 * | |
66 * | +-->group MMgr2
67 * | | ...
68 * | |
69 * | ...
70 * |
71 * +-->window MMw2
72 * ...
74 * For example: a message sent from MMc1_1, from the child side, is
75 * sent only to MMp1_1 on the parent side. However, note that all
76 * message managers in the hierarchy above MMp1_1, in this diagram
77 * MMw1 and MMg, will also notify their message listeners when the
78 * message arrives.
80 * A message sent from MMc2_1 will be sent to MMp2_1 and also notify
81 * all message managers in the hierarchy above that, including the
82 * group message manager MMgr1.
84 * For example: a message broadcast through the global MMg on the
85 * parent side would be broadcast to MMw1, which would transitively
86 * broadcast it to MMp1_1, MM1p_2. The message would next be
87 * broadcast to MMgr1, which would broadcast it to MMp2_1 and MMp2_2.
88 * After that it would broadcast to MMgr2 and then to MMw2, and so
89 * on down the hierarchy.
91 * ***** PERFORMANCE AND SECURITY WARNING *****
92 * Messages broadcast through the global MM and window or group MMs
93 * can result in messages being dispatched across many OS processes,
94 * and to many processes with different permissions. Great care
95 * should be taken when broadcasting.
97 * Interfaces
98 * ----------
100 * The global MMg and window MMw's are message broadcasters implementing
101 * nsIMessageBroadcaster while the frame MMp's are simple message senders
102 * (nsIMessageSender). Their counterparts in the content processes are
103 * message senders implementing nsIContentFrameMessageManager.
105 * nsIMessageListenerManager
106 * / \
107 * nsIMessageSender nsIMessageBroadcaster
109 * nsISyncMessageSender (content process/in-process only)
111 * nsIContentFrameMessageManager (content process/in-process only)
113 * nsIInProcessContentFrameMessageManager (in-process only)
116 * Message managers in the chrome process can also be QI'ed to nsIFrameScriptLoader.
119 * Message managers corresponding to process boundaries
120 * ====================================================
122 * The second realm of message managers is the "process message
123 * managers". With one exception, these always correspond to process
124 * boundaries. The picture looks like
126 * Parent process Child processes
127 * ---------------- -----------------
128 * global (GPPMM)
130 * +-->parent in-process PIPMM<-->child in-process CIPPMM
132 * +-->parent (PPMM1)<------------------>child (CPMM1)
134 * +-->parent (PPMM2)<------------------>child (CPMM2)
135 * ...
137 * Note, PIPMM and CIPPMM both run in the parent process.
139 * For example: the parent-process PPMM1 sends messages to the
140 * child-process CPMM1.
142 * For example: CPMM1 sends messages directly to PPMM1. The global GPPMM
143 * will also notify their message listeners when the message arrives.
145 * For example: messages sent through the global GPPMM will be
146 * dispatched to the listeners of the same-process, CIPPMM, CPMM1,
147 * CPMM2, etc.
149 * ***** PERFORMANCE AND SECURITY WARNING *****
150 * Messages broadcast through the GPPMM can result in messages
151 * being dispatched across many OS processes, and to many processes
152 * with different permissions. Great care should be taken when
153 * broadcasting.
155 * Requests sent to parent-process message listeners should usually
156 * have replies scoped to the requesting CPMM. The following pattern
157 * is common
159 * const ParentProcessListener = {
160 * receiveMessage: function(aMessage) {
161 * let childMM = aMessage.target.QueryInterface(Ci.nsIMessageSender);
162 * switch (aMessage.name) {
163 * case "Foo:Request":
164 * // service request
165 * childMM.sendAsyncMessage("Foo:Response", { data });
168 * };
171 [scriptable, function, uuid(2b44eb57-a9c6-4773-9a1e-fe0818739a4c)]
172 interface nsIMessageListener : nsISupports
175 * This is for JS only.
176 * receiveMessage is called with one parameter, which has the following
177 * properties:
179 * target: %the target of the message. Either an element owning
180 * the message manager, or message manager itself if no
181 * element owns it%
182 * name: %message name%,
183 * sync: %true or false%.
184 * data: %structured clone of the sent message data%,
185 * json: %same as .data, deprecated%,
186 * objects: %named table of jsvals/objects, or null%
187 * principal: %principal for the window app
190 * Each listener is invoked with its own copy of the message
191 * parameter.
193 * When the listener is called, 'this' value is the target of the message.
195 * If the message is synchronous, the possible return value is
196 * returned as JSON (will be changed to use structured clones).
197 * When there are multiple listeners to sync messages, each
198 * listener's return value is sent back as an array. |undefined|
199 * return values show up as undefined values in the array.
201 void receiveMessage();
204 [scriptable, builtinclass, uuid(aae827bd-acf1-45fe-a556-ea545d4c0804)]
205 interface nsIMessageListenerManager : nsISupports
208 * Register |listener| to receive |messageName|. All listener
209 * callbacks for a particular message are invoked when that message
210 * is received.
212 * The message manager holds a strong ref to |listener|.
214 * If the same listener registers twice for the same message, the
215 * second registration is ignored.
217 void addMessageListener(in AString messageName,
218 in nsIMessageListener listener);
221 * Undo an |addMessageListener| call -- that is, calling this causes us to no
222 * longer invoke |listener| when |messageName| is received.
224 * removeMessageListener does not remove a message listener added via
225 * addWeakMessageListener; use removeWeakMessageListener for that.
227 void removeMessageListener(in AString messageName,
228 in nsIMessageListener listener);
231 * This is just like addMessageListener, except the message manager holds a
232 * weak ref to |listener|.
234 * If you have two weak message listeners for the same message, they may be
235 * called in any order.
237 void addWeakMessageListener(in AString messageName,
238 in nsIMessageListener listener);
241 * This undoes an |addWeakMessageListener| call.
243 void removeWeakMessageListener(in AString messageName,
244 in nsIMessageListener listener);
246 [notxpcom] boolean markForCC();
250 * Message "senders" have a single "other side" to which messages are
251 * sent. For example, a child-process message manager will send
252 * messages that are only delivered to its one parent-process message
253 * manager.
255 [scriptable, builtinclass, uuid(d6b0d851-43e6-426d-9f13-054bc0198175)]
256 interface nsIMessageSender : nsIMessageListenerManager
259 * Send |messageName| and |obj| to the "other side" of this message
260 * manager. This invokes listeners who registered for
261 * |messageName|.
263 * See nsIMessageListener::receiveMessage() for the format of the
264 * data delivered to listeners.
265 * @throws NS_ERROR_NOT_INITIALIZED if the sender is not initialized. For
266 * example, we will throw NS_ERROR_NOT_INITIALIZED if we try to send
267 * a message to a cross-process frame but the other process has not
268 * yet been set up.
269 * @throws NS_ERROR_FAILURE when the message receiver cannot be found. For
270 * example, we will throw NS_ERROR_FAILURE if we try to send a message
271 * to a cross-process frame whose process has crashed.
273 [implicit_jscontext, optional_argc]
274 void sendAsyncMessage([optional] in AString messageName,
275 [optional] in jsval obj,
276 [optional] in jsval objects,
277 [optional] in nsIPrincipal principal);
281 * Message "broadcasters" don't have a single "other side" that they
282 * send messages to, but rather a set of subordinate message managers.
283 * For example, broadcasting a message through a window message
284 * manager will broadcast the message to all frame message managers
285 * within its window.
287 [scriptable, builtinclass, uuid(d36346b9-5d3b-497d-9c28-ffbc3e4f6d0d)]
288 interface nsIMessageBroadcaster : nsIMessageListenerManager
291 * Like |sendAsyncMessage()|, but also broadcasts this message to
292 * all "child" message managers of this message manager. See long
293 * comment above for details.
295 * WARNING: broadcasting messages can be very expensive and leak
296 * sensitive data. Use with extreme caution.
298 [implicit_jscontext, optional_argc]
299 void broadcastAsyncMessage([optional] in AString messageName,
300 [optional] in jsval obj,
301 [optional] in jsval objects);
304 * Number of subordinate message managers.
306 readonly attribute unsigned long childCount;
309 * Return a single subordinate message manager.
311 nsIMessageListenerManager getChildAt(in unsigned long aIndex);
314 [scriptable, builtinclass, uuid(7fda0941-9dcc-448b-bd39-16373c5b4003)]
315 interface nsISyncMessageSender : nsIMessageSender
318 * Like |sendAsyncMessage()|, except blocks the sender until all
319 * listeners of the message have been invoked. Returns an array
320 * containing return values from each listener invoked.
322 [implicit_jscontext, optional_argc]
323 jsval sendSyncMessage([optional] in AString messageName,
324 [optional] in jsval obj,
325 [optional] in jsval objects,
326 [optional] in nsIPrincipal principal);
329 * Like |sendSyncMessage()|, except re-entrant. New RPC messages may be
330 * issued even if, earlier on the call stack, we are waiting for a reply
331 * to an earlier sendRpcMessage() call.
333 * Both sendSyncMessage and sendRpcMessage will block until a reply is
334 * received, but they may be temporarily interrupted to process an urgent
335 * incoming message (such as a CPOW request).
337 [implicit_jscontext, optional_argc]
338 jsval sendRpcMessage([optional] in AString messageName,
339 [optional] in jsval obj,
340 [optional] in jsval objects,
341 [optional] in nsIPrincipal principal);
344 [scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
345 interface nsIContentFrameMessageManager : nsISyncMessageSender
348 * The current top level window in the frame or null.
350 readonly attribute nsIDOMWindow content;
353 * The top level docshell or null.
355 readonly attribute nsIDocShell docShell;
358 * Print a string to stdout.
360 void dump(in DOMString aStr);
363 * If leak detection is enabled, print a note to the leak log that this
364 * process will intentionally crash.
366 void privateNoteIntentionalCrash();
369 * Ascii base64 data to binary data and vice versa
371 DOMString atob(in DOMString aAsciiString);
372 DOMString btoa(in DOMString aBase64Data);
375 [uuid(a2325927-9c0c-437d-9215-749c79235031)]
376 interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
378 [notxpcom] nsIContent getOwnerContent();
381 [scriptable, builtinclass, uuid(6fb78110-45ae-11e3-8f96-0800200c9a66)]
382 interface nsIFrameScriptLoader : nsISupports
385 * Load a script in the (remote) frame. aURL must be the absolute URL.
386 * data: URLs are also supported. For example data:,dump("foo\n");
387 * If aAllowDelayedLoad is true, script will be loaded when the
388 * remote frame becomes available. Otherwise the script will be loaded
389 * only if the frame is already available.
391 void loadFrameScript(in AString aURL, in boolean aAllowDelayedLoad,
392 [optional] in boolean aRunInGlobalScope);
395 * Removes aURL from the list of scripts which support delayed load.
397 void removeDelayedFrameScript(in AString aURL);
400 * Returns all delayed scripts that will be loaded once a (remote)
401 * frame becomes available. The return value is a list of pairs
402 * [<URL>, <WasLoadedInGlobalScope>].
404 [implicit_jscontext]
405 jsval getDelayedFrameScripts();
408 [scriptable, builtinclass, uuid(637e8538-4f8f-4a3d-8510-e74386233e19)]
409 interface nsIProcessChecker : nsISupports
411 bool killChild();
414 * Return true if the "remote" process has |aPermission|. This is
415 * intended to be used by JS implementations of cross-process DOM
416 * APIs, like so
418 * recvFooRequest: function(message) {
419 * if (!message.target.assertPermission("foo")) {
420 * return false;
422 * // service foo request
424 * This interface only returns meaningful data when our content is
425 * in a separate process. If it shares the same OS process as us,
426 * then applying this permission check doesn't add any security,
427 * though it doesn't hurt anything either.
429 * Note: If the remote content process does *not* have |aPermission|,
430 * it will be killed as a precaution.
432 boolean assertPermission(in DOMString aPermission);
435 * Return true if the "remote" process has |aManifestURL|. This is
436 * intended to be used by JS implementations of cross-process DOM
437 * APIs, like so
439 * recvFooRequest: function(message) {
440 * if (!message.target.assertContainApp("foo")) {
441 * return false;
443 * // service foo request
445 * This interface only returns meaningful data when our content is
446 * in a separate process. If it shares the same OS process as us,
447 * then applying this manifest URL check doesn't add any security,
448 * though it doesn't hurt anything either.
450 * Note: If the remote content process does *not* contain |aManifestURL|,
451 * it will be killed as a precaution.
453 boolean assertContainApp(in DOMString aManifestURL);
455 boolean assertAppHasPermission(in DOMString aPermission);
458 * Return true if the "remote" process' principal has an appStatus equal to
459 * |aStatus|.
461 * This interface only returns meaningful data when our content is
462 * in a separate process. If it shares the same OS process as us,
463 * then applying this permission check doesn't add any security,
464 * though it doesn't hurt anything either.
466 * Note: If the remote content process does *not* has the |aStatus|,
467 * it will be killed as a precaution.
469 boolean assertAppHasStatus(in unsigned short aStatus);