mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 876397 - Inter-App Communication API (part 2, manifest registry). r=nsm
This commit is contained in:
parent
1f00287b51
commit
a621fc19cd
@ -506,6 +506,7 @@
|
||||
@BINPATH@/components/PushServiceLauncher.js
|
||||
|
||||
@BINPATH@/components/InterAppComm.manifest
|
||||
@BINPATH@/components/InterAppCommService.js
|
||||
@BINPATH@/components/InterAppConnection.js
|
||||
@BINPATH@/components/InterAppMessagePort.js
|
||||
|
||||
|
@ -551,6 +551,10 @@ ManifestHelper.prototype = {
|
||||
return this._localeProp("description");
|
||||
},
|
||||
|
||||
get type() {
|
||||
return this._localeProp("type");
|
||||
},
|
||||
|
||||
get version() {
|
||||
return this._localeProp("version");
|
||||
},
|
||||
|
@ -6,3 +6,7 @@ contract @mozilla.org/dom/inter-app-connection-request;1 {6a77e9e0-0645-11e3-b90
|
||||
|
||||
component {c66e0f8c-e3cb-11e2-9e85-43ef6244b884} InterAppMessagePort.js
|
||||
contract @mozilla.org/dom/inter-app-message-port;1 {c66e0f8c-e3cb-11e2-9e85-43ef6244b884}
|
||||
|
||||
component {3dd15ce6-e7be-11e2-82bc-77967e7a63e6} InterAppCommService.js
|
||||
contract @mozilla.org/inter-app-communication-service;1 {3dd15ce6-e7be-11e2-82bc-77967e7a63e6}
|
||||
category profile-after-change InterAppCommService @mozilla.org/inter-app-communication-service;1
|
||||
|
113
dom/apps/src/InterAppCommService.js
Normal file
113
dom/apps/src/InterAppCommService.js
Normal file
@ -0,0 +1,113 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function debug(aMsg) {
|
||||
// dump("-- InterAppCommService: " + Date.now() + ": " + aMsg + "\n");
|
||||
}
|
||||
|
||||
function InterAppCommService() {
|
||||
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||
|
||||
// This matrix is used for saving the inter-app connection info registered in
|
||||
// the app manifest. The object literal is defined as below:
|
||||
//
|
||||
// {
|
||||
// "keyword1": {
|
||||
// "subAppManifestURL1": {
|
||||
// /* subscribed info */
|
||||
// },
|
||||
// "subAppManifestURL2": {
|
||||
// /* subscribed info */
|
||||
// },
|
||||
// ...
|
||||
// },
|
||||
// "keyword2": {
|
||||
// "subAppManifestURL3": {
|
||||
// /* subscribed info */
|
||||
// },
|
||||
// ...
|
||||
// },
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// {
|
||||
// "foo": {
|
||||
// "app://subApp1.gaiamobile.org/manifest.webapp": {
|
||||
// pageURL: "app://subApp1.gaiamobile.org/handler.html",
|
||||
// description: "blah blah",
|
||||
// appStatus: Ci.nsIPrincipal.APP_STATUS_CERTIFIED,
|
||||
// rules: { ... }
|
||||
// },
|
||||
// "app://subApp2.gaiamobile.org/manifest.webapp": {
|
||||
// pageURL: "app://subApp2.gaiamobile.org/handler.html",
|
||||
// description: "blah blah",
|
||||
// appStatus: Ci.nsIPrincipal.APP_STATUS_PRIVILEGED,
|
||||
// rules: { ... }
|
||||
// }
|
||||
// },
|
||||
// "bar": {
|
||||
// "app://subApp3.gaiamobile.org/manifest.webapp": {
|
||||
// pageURL: "app://subApp3.gaiamobile.org/handler.html",
|
||||
// description: "blah blah",
|
||||
// appStatus: Ci.nsIPrincipal.APP_STATUS_INSTALLED,
|
||||
// rules: { ... }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// TODO Bug 908999 - Update registered connections when app gets uninstalled.
|
||||
this._registeredConnections = {};
|
||||
}
|
||||
|
||||
InterAppCommService.prototype = {
|
||||
registerConnection: function(aKeyword, aHandlerPageURI, aManifestURI,
|
||||
aDescription, aAppStatus, aRules) {
|
||||
let manifestURL = aManifestURI.spec;
|
||||
let pageURL = aHandlerPageURI.spec;
|
||||
|
||||
debug("registerConnection: aKeyword: " + aKeyword +
|
||||
" manifestURL: " + manifestURL + " pageURL: " + pageURL +
|
||||
" aDescription: " + aDescription + " aAppStatus: " + aAppStatus +
|
||||
" aRules.minimumAccessLevel: " + aRules.minimumAccessLevel +
|
||||
" aRules.manifestURLs: " + aRules.manifestURLs +
|
||||
" aRules.installOrigins: " + aRules.installOrigins);
|
||||
|
||||
let subAppManifestURLs = this._registeredConnections[aKeyword];
|
||||
if (!subAppManifestURLs) {
|
||||
subAppManifestURLs = this._registeredConnections[aKeyword] = {};
|
||||
}
|
||||
|
||||
subAppManifestURLs[manifestURL] = {
|
||||
pageURL: pageURL,
|
||||
description: aDescription,
|
||||
appStatus: aAppStatus,
|
||||
rules: aRules,
|
||||
manifestURL: manifestURL
|
||||
};
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "xpcom-shutdown":
|
||||
Services.obs.removeObserver(this, "xpcom-shutdown");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
classID: Components.ID("{3dd15ce6-e7be-11e2-82bc-77967e7a63e6}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterAppCommService,
|
||||
Ci.nsIObserver])
|
||||
}
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([InterAppCommService]);
|
@ -60,6 +60,11 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "interAppCommService", function() {
|
||||
return Cc["@mozilla.org/inter-app-communication-service;1"]
|
||||
.getService(Ci.nsIInterAppCommService);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
|
||||
return Cc["@mozilla.org/system-message-internal;1"]
|
||||
.getService(Ci.nsISystemMessagesInternal);
|
||||
@ -530,6 +535,8 @@ this.DOMApplicationRegistry = {
|
||||
|
||||
// |aEntryPoint| is either the entry_point name or the null in which case we
|
||||
// use the root of the manifest.
|
||||
//
|
||||
// TODO Bug 908094 Refine _registerSystemMessagesForEntryPoint(...).
|
||||
_registerSystemMessagesForEntryPoint: function(aManifest, aApp, aEntryPoint) {
|
||||
let root = aManifest;
|
||||
if (aEntryPoint && aManifest.entry_points[aEntryPoint]) {
|
||||
@ -571,6 +578,69 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
},
|
||||
|
||||
// |aEntryPoint| is either the entry_point name or the null in which case we
|
||||
// use the root of the manifest.
|
||||
//
|
||||
// TODO Bug 908094 Refine _registerInterAppConnectionsForEntryPoint(...).
|
||||
_registerInterAppConnectionsForEntryPoint: function(aManifest, aApp,
|
||||
aEntryPoint) {
|
||||
let root = aManifest;
|
||||
if (aEntryPoint && aManifest.entry_points[aEntryPoint]) {
|
||||
root = aManifest.entry_points[aEntryPoint];
|
||||
}
|
||||
|
||||
let connections = root.connections;
|
||||
if (!connections) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((typeof connections) !== "object") {
|
||||
debug("|connections| is not an object. Skipping: " + connections);
|
||||
return;
|
||||
}
|
||||
|
||||
let manifest = new ManifestHelper(aManifest, aApp.origin);
|
||||
let launchPathURI = Services.io.newURI(manifest.fullLaunchPath(aEntryPoint),
|
||||
null, null);
|
||||
let manifestURI = Services.io.newURI(aApp.manifestURL, null, null);
|
||||
|
||||
for (let keyword in connections) {
|
||||
let connection = connections[keyword];
|
||||
|
||||
// Resolve the handler path from origin. If |handler_path| is absent,
|
||||
// use |launch_path| as default.
|
||||
let fullHandlerPath;
|
||||
let handlerPath = connection.handler_path;
|
||||
if (handlerPath) {
|
||||
try {
|
||||
fullHandlerPath = manifest.resolveFromOrigin(handlerPath);
|
||||
} catch(e) {
|
||||
debug("Connection's handler path is invalid. Skipping: keyword: " +
|
||||
keyword + " handler_path: " + handlerPath);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let handlerPageURI = fullHandlerPath
|
||||
? Services.io.newURI(fullHandlerPath, null, null)
|
||||
: launchPathURI;
|
||||
|
||||
if (SystemMessagePermissionsChecker
|
||||
.isSystemMessagePermittedToRegister("connection",
|
||||
aApp.origin,
|
||||
aManifest)) {
|
||||
msgmgr.registerPage("connection", handlerPageURI, manifestURI);
|
||||
}
|
||||
|
||||
interAppCommService.
|
||||
registerConnection(keyword,
|
||||
handlerPageURI,
|
||||
manifestURI,
|
||||
connection.description,
|
||||
AppsUtils.getAppManifestStatus(manifest),
|
||||
connection.rules);
|
||||
}
|
||||
},
|
||||
|
||||
_registerSystemMessages: function(aManifest, aApp) {
|
||||
this._registerSystemMessagesForEntryPoint(aManifest, aApp, null);
|
||||
|
||||
@ -583,6 +653,19 @@ this.DOMApplicationRegistry = {
|
||||
}
|
||||
},
|
||||
|
||||
_registerInterAppConnections: function(aManifest, aApp) {
|
||||
this._registerInterAppConnectionsForEntryPoint(aManifest, aApp, null);
|
||||
|
||||
if (!aManifest.entry_points) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let entryPoint in aManifest.entry_points) {
|
||||
this._registerInterAppConnectionsForEntryPoint(aManifest, aApp,
|
||||
entryPoint);
|
||||
}
|
||||
},
|
||||
|
||||
// |aEntryPoint| is either the entry_point name or the null in which case we
|
||||
// use the root of the manifest.
|
||||
_createActivitiesToRegister: function(aManifest, aApp, aEntryPoint, aRunUpdate) {
|
||||
@ -745,6 +828,7 @@ this.DOMApplicationRegistry = {
|
||||
app.redirects = this.sanitizeRedirects(manifest.redirects);
|
||||
}
|
||||
this._registerSystemMessages(manifest, app);
|
||||
this._registerInterAppConnections(manifest, app);
|
||||
appsToRegister.push({ manifest: manifest, app: app });
|
||||
}, this);
|
||||
this._registerActivitiesForApps(appsToRegister, aRunUpdate);
|
||||
@ -1396,6 +1480,7 @@ this.DOMApplicationRegistry = {
|
||||
}
|
||||
this._registerSystemMessages(aNewManifest, aApp);
|
||||
this._registerActivities(aNewManifest, aApp, true);
|
||||
this._registerInterAppConnections(aNewManifest, aApp);
|
||||
} else {
|
||||
// Nothing else to do but notifying we're ready.
|
||||
this.notifyAppsRegistryReady();
|
||||
|
@ -16,6 +16,7 @@ EXTRA_COMPONENTS += [
|
||||
'AppsService.js',
|
||||
'AppsService.manifest',
|
||||
'InterAppComm.manifest',
|
||||
'InterAppCommService.js',
|
||||
'InterAppConnection.js',
|
||||
'InterAppMessagePort.js',
|
||||
'Webapps.js',
|
||||
|
@ -11,6 +11,7 @@ XPIDL_SOURCES += [
|
||||
'nsIDOMApplicationRegistry.idl',
|
||||
'nsIDOMApplicationRegistry2.idl',
|
||||
'nsIDOMMozApplicationEvent.idl',
|
||||
'nsIInterAppCommService.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_apps'
|
||||
|
40
dom/interfaces/apps/nsIInterAppCommService.idl
Normal file
40
dom/interfaces/apps/nsIInterAppCommService.idl
Normal file
@ -0,0 +1,40 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface nsIURI;
|
||||
|
||||
/**
|
||||
* Implemented by the contract id @mozilla.org/inter-app-communication-service;1
|
||||
*
|
||||
* This interface contains helpers for Inter-App Communication API [1] related
|
||||
* purposes. A singleton service of this interface will be instantiated during
|
||||
* the system boot-up, which plays the role of the central service receiving
|
||||
* messages from and interacting with the content processes.
|
||||
*
|
||||
* [1] https://wiki.mozilla.org/WebAPI/Inter_App_Communication_Alt_proposal
|
||||
*/
|
||||
[scriptable, uuid(7fdd8b68-0b0a-11e3-9b4c-afbc236da250)]
|
||||
interface nsIInterAppCommService : nsISupports
|
||||
{
|
||||
/*
|
||||
* Registration of a page that wants to be connected to other apps through
|
||||
* the Inter-App Communication API.
|
||||
*
|
||||
* @param keyword The connection's keyword.
|
||||
* @param handlerPageURI The URI of the handler's page.
|
||||
* @param manifestURI The webapp's manifest URI.
|
||||
* @param description The connection's description.
|
||||
* @param appStatus The app status can be Ci.nsIPrincipal.APP_STATUS_[
|
||||
* NOT_INSTALLED, INSTALLED, PRIVILEGED, CERTIFIED].
|
||||
* @param rules The connection's rules.
|
||||
*/
|
||||
void registerConnection(in DOMString keyword,
|
||||
in nsIURI handlerPageURI,
|
||||
in nsIURI manifestURI,
|
||||
in DOMString description,
|
||||
in unsigned short appStatus,
|
||||
in jsval rules);
|
||||
};
|
Loading…
Reference in New Issue
Block a user