From 7c56c3e4416af1890f0c462217c755b642993c2d Mon Sep 17 00:00:00 2001 From: Gene Lian Date: Sat, 17 Aug 2013 22:40:01 +0800 Subject: [PATCH] Bug 876397 - Inter-App Communication API (part 4, getConnections()). r=nsm --- dom/apps/src/InterAppCommService.js | 69 ++++++++++++++++++++++++++++- dom/apps/src/InterAppConnection.js | 31 ++++++++++++- dom/apps/src/Webapps.js | 24 ++++++++-- 3 files changed, 118 insertions(+), 6 deletions(-) diff --git a/dom/apps/src/InterAppCommService.js b/dom/apps/src/InterAppCommService.js index 341ab2611b5..59e7a4e498b 100644 --- a/dom/apps/src/InterAppCommService.js +++ b/dom/apps/src/InterAppCommService.js @@ -30,7 +30,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "messenger", "@mozilla.org/system-message-internal;1", "nsISystemMessagesInternal"); -const kMessages =["Webapps:Connect"]; +const kMessages =["Webapps:Connect", + "Webapps:GetConnections", + "InterAppConnection:Cancel"]; function InterAppCommService() { Services.obs.addObserver(this, "xpcom-shutdown", false); @@ -455,6 +457,65 @@ InterAppCommService.prototype = { selectedApps: appsToSelect })); }, + _getConnections: function(aMessage, aTarget) { + let outerWindowID = aMessage.outerWindowID; + let requestID = aMessage.requestID; + + let connections = []; + for (let keyword in this._allowedConnections) { + let allowedPubAppManifestURLs = this._allowedConnections[keyword]; + for (let allowedPubAppManifestURL in allowedPubAppManifestURLs) { + let allowedSubAppManifestURLs = + allowedPubAppManifestURLs[allowedPubAppManifestURL]; + allowedSubAppManifestURLs.forEach(function(allowedSubAppManifestURL) { + connections.push({ keyword: keyword, + pubAppManifestURL: allowedPubAppManifestURL, + subAppManifestURL: allowedSubAppManifestURL }); + }); + } + } + + aTarget.sendAsyncMessage("Webapps:GetConnections:Return:OK", + { connections: connections, + oid: outerWindowID, requestID: requestID }); + }, + + _cancelConnection: function(aMessage) { + let keyword = aMessage.keyword; + let pubAppManifestURL = aMessage.pubAppManifestURL; + let subAppManifestURL = aMessage.subAppManifestURL; + + let allowedPubAppManifestURLs = this._allowedConnections[keyword]; + if (!allowedPubAppManifestURLs) { + debug("keyword is not found: " + keyword); + return; + } + + let allowedSubAppManifestURLs = + allowedPubAppManifestURLs[pubAppManifestURL]; + if (!allowedSubAppManifestURLs) { + debug("publisher is not found: " + pubAppManifestURL); + return; + } + + let index = allowedSubAppManifestURLs.indexOf(subAppManifestURL); + if (index == -1) { + debug("subscriber is not found: " + subAppManifestURL); + return; + } + + debug("Cancelling the connection."); + allowedSubAppManifestURLs.splice(index, 1); + + // Clean up the parent entries if needed. + if (allowedSubAppManifestURLs.length == 0) { + delete allowedPubAppManifestURLs[pubAppManifestURL]; + if (Object.keys(allowedPubAppManifestURLs).length == 0) { + delete this._allowedConnections[keyword]; + } + } + }, + _handleSelectcedApps: function(aData) { let callerID = aData.callerID; let caller = this._promptUICallers[callerID]; @@ -521,6 +582,12 @@ InterAppCommService.prototype = { case "Webapps:Connect": this._connect(message, target); break; + case "Webapps:GetConnections": + this._getConnections(message, target); + break; + case "InterAppConnection:Cancel": + this._cancelConnection(message); + break; } }, diff --git a/dom/apps/src/InterAppConnection.js b/dom/apps/src/InterAppConnection.js index 1e8163b15ca..59ae047e71c 100644 --- a/dom/apps/src/InterAppConnection.js +++ b/dom/apps/src/InterAppConnection.js @@ -8,6 +8,15 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "cpmm", + "@mozilla.org/childprocessmessagemanager;1", + "nsIMessageSender"); + +XPCOMUtils.defineLazyServiceGetter(this, "appsService", + "@mozilla.org/AppsService;1", + "nsIAppsService"); function debug(aMsg) { // dump("-- InterAppConnection: " + Date.now() + ": " + aMsg + "\n"); @@ -25,13 +34,16 @@ function InterAppConnection() { }; InterAppConnection.prototype = { + __proto__: DOMRequestIpcHelper.prototype, + classDescription: "MozInterAppConnection", classID: Components.ID("{9dbfa904-0718-11e3-8e77-0721a45514b8}"), contractID: "@mozilla.org/dom/inter-app-connection;1", - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, + Ci.nsISupportsWeakReference]), __init: function(aKeyword, aPublisher, aSubscriber) { debug("__init: aKeyword: " + aKeyword + @@ -41,8 +53,23 @@ InterAppConnection.prototype = { this.subscriber = aSubscriber; }, + // Ci.nsIDOMGlobalPropertyInitializer implementation. + init: function(aWindow) { + debug("init"); + + this.initDOMRequestHelper(aWindow, []); + let principal = aWindow.document.nodePrincipal; + this._manifestURL = appsService.getManifestURLByLocalId(principal.appId); + }, + cancel: function() { - // TODO + debug("cancel"); + + cpmm.sendAsyncMessage("InterAppConnection:Cancel", + { keyword: this.keyword, + pubAppManifestURL: this.publisher, + subAppManifestURL: this.subscriber, + manifestURL: this._manifestURL }); } }; diff --git a/dom/apps/src/Webapps.js b/dom/apps/src/Webapps.js index d7f7bf0d8c4..5617c06fda4 100644 --- a/dom/apps/src/Webapps.js +++ b/dom/apps/src/Webapps.js @@ -346,7 +346,8 @@ WebappsApplication.prototype = { "Webapps:PackageEvent", "Webapps:ClearBrowserData:Return", "Webapps:Connect:Return:OK", - "Webapps:Connect:Return:KO"]); + "Webapps:Connect:Return:KO", + "Webapps:GetConnections:Return:OK"]); cpmm.sendAsyncMessage("Webapps:RegisterForMessages", ["Webapps:OfflineCache", @@ -477,7 +478,12 @@ WebappsApplication.prototype = { }, getConnections: function() { - // TODO + return this.createPromise(function (aResolver) { + cpmm.sendAsyncMessage("Webapps:GetConnections", + { manifestURL: this.manifestURL, + outerWindowID: this._id, + requestID: this.getPromiseResolverId(aResolver) }); + }.bind(this)); }, uninit: function() { @@ -501,7 +507,8 @@ WebappsApplication.prototype = { let msg = aMessage.json; let req; if (aMessage.name == "Webapps:Connect:Return:OK" || - aMessage.name == "Webapps:Connect:Return:KO") { + aMessage.name == "Webapps:Connect:Return:KO" || + aMessage.name == "Webapps:GetConnections:Return:OK") { req = this.takePromiseResolver(msg.requestID); } else { req = this.takeRequest(msg.requestID); @@ -641,6 +648,17 @@ WebappsApplication.prototype = { case "Webapps:Connect:Return:KO": req.reject("No connections registered"); break; + case "Webapps:GetConnections:Return:OK": + let connections = []; + msg.connections.forEach(function(aConnection) { + let connection = + new this._window.MozInterAppConnection(aConnection.keyword, + aConnection.pubAppManifestURL, + aConnection.subAppManifestURL); + connections.push(connection); + }, this); + req.resolve(connections); + break; } },