Skip to content

AndroidMessaging

minj edited this page Mar 19, 2015 · 1 revision

Source: NoScript/mozcamp11

Parent (chrome) process

let mm = window.messageManager;
mm.addMessageListener("example:click", function(msg) {
	let browser = msg.target;
	let data = {text: "<" + msg.json.tagName + "> clicked!"};
	browser.messageManager
		.sendAsyncMessage("example:alert", data);
});

mm.loadFrameScript(EXAMPLE_BASE_URL + "/content.js", true);

Child (content) process

/* content.js frame script */
addEventListener("click", function(event) {
	let data = {tagName: event.target.tagName};
	sendAsyncMessage("example:click", data);
}, false);

addMessageListener("example:alert", function(msg) {	
	alert(msg.json.text);
});

Chatty processes...

Big fat API (common)

interface nsIFrameMessageListener : nsISupports {
	void receiveMessage({name, sync, json, objects} aMessage);
};

interface nsIFrameMessageManager : nsISupports {
	void addMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
	void removeMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
	void sendAsyncMessage([optional] in AString messageName, [optional] in jsval obj);
};

Big fat API (parent)

interface nsIFrameMessageListener : nsISupports {
	void receiveMessage({name, sync, json, objects} aMessage);
};

interface nsIFrameMessageManager : nsISupports {
	void addMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
	void removeMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
	void sendAsyncMessage([optional] in AString messageName, [optional] in jsval obj);
};
	
interface nsITreeItemFrameMessageManager : nsIFrameMessageManager {
	readonly attribute unsigned long childCount;
	nsITreeItemFrameMessageManager getChildAt(in unsigned long aIndex);
};

interface nsIChromeFrameMessageManager : nsITreeItemFrameMessageManager
{
	void loadFrameScript(in AString aURL, in boolean aDelayedLoad);
	void removeDelayedFrameScript(in AString aURL);
};

Big fat API (child)

interface nsIFrameMessageListener : nsISupports {
	void receiveMessage({name, sync, json, objects} aMessage);
};

interface nsIFrameMessageManager : nsISupports {
	void addMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
	void removeMessageListener(in AString aMessage, in nsIFrameMessageListener aListener);
	void sendAsyncMessage([optional] in AString messageName, [optional] in jsval obj);
};
 
interface nsISyncMessageSender : nsIFrameMessageManager {
	// Returns an array of JSON objects.
	jsval sendSyncMessage([optional] in AString messageName, [optional] in jsval obj);
};

interface nsIContentFrameMessageManager : nsISyncMessageSender {
	readonly attribute nsIDOMWindow content;
	readonly attribute nsIDocShell docShell;
	void dump(in DOMString aStr);
	DOMString atob(in DOMString aAsciiString);
	DOMString btoa(in DOMString aBase64Data);
};

It's raining message managers!

// Global (to communicate with any content script)
Cc["@mozilla.org/globalmessagemanager;1"]
	.getService(Ci.nsIChromeFrameMessageManager)

// per chrome window (talks with its browsers' content)
window.messageManager

// per browser window (talks with this browser's content only)
browser.messageManager

// Frame script context is a nsIContentFrameMessageManager

// Parent (in chrome, when no window/frame script is available)
Cc["@mozilla.org/parentprocessmessagemanager;1"]
	.getService(Ci.nsIFrameMessageManager);
	
// Child (in content modules with no frame script)
Cc["@mozilla.org/childprocessmessagemanager;1"]
	.getService(Ci.nsISyncMessageSender);