From eed40771dd2551f02719d3182a508a7c38747365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20Desr=C3=A9?= Date: Thu, 15 Dec 2011 09:20:57 -0800 Subject: [PATCH] Bug 709875 - add enumerateAll to navigator.mozApps API [r=gal] --- dom/base/Webapps.js | 12 +++++ dom/base/Webapps.jsm | 29 ++++++++--- .../apps/nsIDOMApplicationRegistry.idl | 52 ++++++++++++++++++- 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/dom/base/Webapps.js b/dom/base/Webapps.js index b8553bb7361c..2c04c6aa8ab9 100644 --- a/dom/base/Webapps.js +++ b/dom/base/Webapps.js @@ -237,6 +237,18 @@ WebappsRegistry.prototype = { callbackID: this.getCallbackId({ success: aSuccess, error: aError }) }); }, + enumerateAll: function(aSuccess, aError) { + if (this.hasPrivileges) { + this.mm.sendAsyncMessage("Webapps:EnumerateAll", { from: this._window.location.href, + origin: this._getOrigin(this._window.location.href), + oid: this._id, + callbackID: this.getCallbackId({ success: aSuccess, error: aError }) }); + } else { + if (aError) + aError.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED)); + } + }, + observe: function(aSubject, aTopic, aData) { let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data; if (wId == this.innerWindowID) { diff --git a/dom/base/Webapps.jsm b/dom/base/Webapps.jsm index 743f8801cfd7..0c3f9f541be4 100644 --- a/dom/base/Webapps.jsm +++ b/dom/base/Webapps.jsm @@ -57,7 +57,7 @@ let DOMApplicationRegistry = { init: function() { this.mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager); let messages = ["Webapps:Install", "Webapps:Uninstall", - "Webapps:Enumerate", "Webapps:Launch"]; + "Webapps:Enumerate", "Webapps:EnumerateAll", "Webapps:Launch"]; messages.forEach((function(msgName) { this.mm.addMessageListener(msgName, this); @@ -70,6 +70,14 @@ let DOMApplicationRegistry = { return; this._loadJSONAsync(this.appsFile, (function(aData) { this.webapps = aData; }).bind(this)); + + try { + let hosts = Services.prefs.getCharPref("dom.mozApps.whitelist") + hosts.split(",").forEach(function(aHost) { + Services.perms.add(Services.io.newURI(aHost, null, null), "webapps-manage", + Ci.nsIPermissionManager.ALLOW_ACTION); + }); + } catch(e) { } }, _loadJSONAsync: function(aFile, aCallback) { @@ -125,10 +133,10 @@ let DOMApplicationRegistry = { Services.obs.notifyObservers(this, "webapps-launch", JSON.stringify(msg)); break; case "Webapps:Enumerate": - if (hasPrivileges) - this.enumerateAll(msg) - else - this.enumerate(msg); + this.enumerate(msg); + break; + case "Webapps:EnumerateAll": + this.enumerateAll(msg); break; } }, @@ -208,6 +216,11 @@ let DOMApplicationRegistry = { * Asynchronously reads a list of manifests */ _readManifests: function(aData, aFinalCallback, aIndex) { + if (!aData.length) { + aFinalCallback(aData); + return; + } + let index = aIndex || 0; let id = aData[index].id; let file = FileUtils.getFile("ProfD", ["webapps", id, "manifest.json"], true); @@ -239,6 +252,7 @@ let DOMApplicationRegistry = { enumerate: function(aData) { aData.apps = []; let tmp = []; + let selfId; let id = this._appId(aData.origin); // if it's an app, add itself to the result @@ -246,12 +260,13 @@ let DOMApplicationRegistry = { let app = this._cloneAppObject(this.webapps[id]); aData.apps.push(app); tmp.push({ id: id }); + selfId = id; } // check if it's a store. let isStore = false; for (id in this.webapps) { - let app = this._cloneAppObject(this.webapps[id]); + let app = this.webapps[id]; if (app.installOrigin == aData.origin) { isStore = true; break; @@ -261,6 +276,8 @@ let DOMApplicationRegistry = { // add all the apps from this store if (isStore) { for (id in this.webapps) { + if (id == selfId) + continue; let app = this._cloneAppObject(this.webapps[id]); if (app.installOrigin == aData.origin) { aData.apps.push(app); diff --git a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl index 5533a1b77fe6..1f69cc5e4509 100644 --- a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl +++ b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl @@ -73,17 +73,67 @@ interface mozIDOMApplicationRegistryErrorCallback : nsISupports void handleEvent(in mozIDOMApplicationRegistryError error); }; -[scriptable, uuid(4070ea6f-dca1-4052-8bc6-7a9bcfc314ac)] +[scriptable, uuid(ac63c0ba-1f33-4e3e-b9aa-6a3243a9adba)] interface mozIDOMApplicationRegistry : nsISupports { + /** + * Install a web app. onerror can be used to report errors, + * and oninstall if the caller is privileged. + * + * @param manifestUrl : the URL of the webapps manifest + * @param receipt : An opaque string used to track payment status + */ void install(in DOMString manifestUrl, [optional] in DOMString receipt); + + /** + * This call is only accessible to privileged callers. + * + * @param origin : the origin of the application to uninstall. + */ void uninstall(in DOMString origin); + + /** + * Enumerate apps : either return itself if caller is an app, or + * apps installed from a store if caller is a store + * + * @param success: the callback that will get the array of applications + * @param error: optional error callback + */ void enumerate(in mozIDOMApplicationRegistryEnumerateCallback success, [optional] in mozIDOMApplicationRegistryErrorCallback error); + + /** + * Enumerate all apps installed from all stores. + * Only usable by privileged callers. + * + * @param success: the callback that will get the array of applications + * @param error: optional error callback + */ + void enumerateAll(in mozIDOMApplicationRegistryEnumerateCallback success, + [optional] in mozIDOMApplicationRegistryErrorCallback error); + + /** + * launch a webapp. Behavior is application dependant. + * + * @param origin : the origin of the application to launch + */ void launch(in DOMString origin); + /** + * event listener to get notified of application installs. Only settable by + * privileged callers + */ attribute nsIDOMEventListener oninstall; + + /** + * event listener to get notified of application uninstalls. Only settable by + * privileged callers + */ attribute nsIDOMEventListener onuninstall; + + /** + * event listener to get notified of errors. + */ attribute nsIDOMEventListener onerror; };