From 48fcec0055fd40382645b28e7dd4f35c6bff86d0 Mon Sep 17 00:00:00 2001 From: Gene Lian Date: Fri, 11 Jan 2013 20:50:46 +0800 Subject: [PATCH] Bug 820206 - Validate "Webapps:*" message parameters in the parent process (part 1, move .uninstall() from mozIDOMApplication to mozIDOMApplicationMgmt). r=sicking, a=blocking-basecamp --- dom/apps/src/Webapps.js | 77 +++++++++++-------- dom/apps/src/Webapps.jsm | 13 ++-- .../apps/nsIDOMApplicationRegistry.idl | 14 +++- 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/dom/apps/src/Webapps.js b/dom/apps/src/Webapps.js index 4432147f2601..e4bf357018ef 100644 --- a/dom/apps/src/Webapps.js +++ b/dom/apps/src/Webapps.js @@ -348,16 +348,15 @@ WebappsApplication.prototype = { this._downloadError = null; - this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", - "Webapps:Uninstall:Return:KO", - "Webapps:OfflineCache", + this.initHelper(aWindow, ["Webapps:OfflineCache", "Webapps:CheckForUpdate:Return:OK", "Webapps:CheckForUpdate:Return:KO", "Webapps:PackageEvent"]); cpmm.sendAsyncMessage("Webapps:RegisterForMessages", - ["Webapps:Uninstall:Return:OK", "Webapps:OfflineCache", - "Webapps:PackageEvent", "Webapps:CheckForUpdate:Return:OK"]); + ["Webapps:OfflineCache", + "Webapps:PackageEvent", + "Webapps:CheckForUpdate:Return:OK"]); }, get manifest() { @@ -443,14 +442,6 @@ WebappsApplication.prototype = { return request; }, - uninstall: function() { - let request = this.createRequest(); - cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this.origin, - oid: this._id, - requestID: this.getRequestId(request) }); - return request; - }, - clearBrowserData: function() { let browserChild = BrowserElementPromptService.getBrowserElementChildForWindow(this._window); @@ -462,8 +453,9 @@ WebappsApplication.prototype = { uninit: function() { this._onprogress = null; cpmm.sendAsyncMessage("Webapps:UnregisterForMessages", - ["Webapps:Uninstall:Return:OK", "Webapps:OfflineCache", - "Webapps:PackageEvent", "Webapps:CheckForUpdate:Return:OK"]); + ["Webapps:OfflineCache", + "Webapps:PackageEvent", + "Webapps:CheckForUpdate:Return:OK"]); }, _fireEvent: function(aName, aHandler) { @@ -484,18 +476,9 @@ WebappsApplication.prototype = { aMessage.name !== "Webapps:CheckForUpdate:Return:OK") return; switch (aMessage.name) { - case "Webapps:Uninstall:Return:OK": - Services.DOMRequest.fireSuccess(req, msg.origin); - break; - case "Webapps:Uninstall:Return:KO": - Services.DOMRequest.fireError(req, "NOT_INSTALLED"); - break; case "Webapps:Launch:Return:KO": Services.DOMRequest.fireError(req, "APP_INSTALL_PENDING"); break; - case "Webapps:Uninstall:Return:KO": - Services.DOMRequest.fireError(req, "NOT_INSTALLED"); - break; case "Webapps:CheckForUpdate:Return:KO": Services.DOMRequest.fireError(req, msg.error); break; @@ -603,12 +586,18 @@ function WebappsApplicationMgmt(aWindow) { //only pages with perm set can use some functions this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION; - this.initHelper(aWindow, ["Webapps:GetAll:Return:OK", "Webapps:GetAll:Return:KO", - "Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK", + this.initHelper(aWindow, ["Webapps:GetAll:Return:OK", + "Webapps:GetAll:Return:KO", + "Webapps:Uninstall:Return:OK", + "Webapps:Uninstall:Broadcast:Return:OK", + "Webapps:Uninstall:Return:KO", + "Webapps:Install:Return:OK", "Webapps:GetNotInstalled:Return:OK"]); cpmm.sendAsyncMessage("Webapps:RegisterForMessages", - ["Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK"]); + ["Webapps:Install:Return:OK", + "Webapps:Uninstall:Return:OK", + "Webapps:Uninstall:Broadcast:Return:OK"]); this._oninstall = null; this._onuninstall = null; @@ -628,7 +617,9 @@ WebappsApplicationMgmt.prototype = { this._oninstall = null; this._onuninstall = null; cpmm.sendAsyncMessage("Webapps:UnregisterForMessages", - ["Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK"]); + ["Webapps:Install:Return:OK", + "Webapps:Uninstall:Return:OK", + "Webapps:Uninstall:Broadcast:Return:OK"]); }, applyDownload: function(aApp) { @@ -640,6 +631,14 @@ WebappsApplicationMgmt.prototype = { { manifestURL: aApp.manifestURL }); }, + uninstall: function(aApp) { + let request = this.createRequest(); + cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: aApp.origin, + oid: this._id, + requestID: this.getRequestId(request) }); + return request; + }, + getAll: function() { let request = this.createRequest(); cpmm.sendAsyncMessage("Webapps:GetAll", { oid: this._id, @@ -680,11 +679,13 @@ WebappsApplicationMgmt.prototype = { receiveMessage: function(aMessage) { var msg = aMessage.json; let req = this.getRequest(msg.requestID); - // We want Webapps:Install:Return:OK and Webapps:Uninstall:Return:OK to be boradcasted - // to all instances of mozApps.mgmt - if (!((msg.oid == this._id && req) - || aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK")) + // We want Webapps:Install:Return:OK and Webapps:Uninstall:Broadcast:Return:OK + // to be boradcasted to all instances of mozApps.mgmt. + if (!((msg.oid == this._id && req) || + aMessage.name == "Webapps:Install:Return:OK" || + aMessage.name == "Webapps:Uninstall:Broadcast:Return:OK")) { return; + } switch (aMessage.name) { case "Webapps:GetAll:Return:OK": Services.DOMRequest.fireSuccess(req, convertAppsArray(msg.apps, this._window)); @@ -703,7 +704,7 @@ WebappsApplicationMgmt.prototype = { this._oninstall.handleEvent(event); } break; - case "Webapps:Uninstall:Return:OK": + case "Webapps:Uninstall:Broadcast:Return:OK": if (this._onuninstall) { let detail = { manifestURL: msg.manifestURL, @@ -714,8 +715,16 @@ WebappsApplicationMgmt.prototype = { this._onuninstall.handleEvent(event); } break; + case "Webapps:Uninstall:Return:OK": + Services.DOMRequest.fireSuccess(req, msg.origin); + break; + case "Webapps:Uninstall:Return:KO": + Services.DOMRequest.fireError(req, "NOT_INSTALLED"); + break; + } + if (aMessage.name !== "Webapps:Uninstall:Broadcast:Return:OK") { + this.removeRequest(msg.requestID); } - this.removeRequest(msg.requestID); }, classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"), diff --git a/dom/apps/src/Webapps.jsm b/dom/apps/src/Webapps.jsm index 5f41f87df6df..f1650a445b74 100644 --- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -746,10 +746,11 @@ this.DOMApplicationRegistry = { Services.prefs.setBoolPref("dom.mozApps.used", true); // We need to check permissions for calls coming from mozApps.mgmt. - // These are: getAll(), getNotInstalled() and applyDownload() + // These are: getAll(), getNotInstalled(), applyDownload() and uninstall(). if (["Webapps:GetAll", "Webapps:GetNotInstalled", - "Webapps:ApplyDownload"].indexOf(aMessage.name) != -1) { + "Webapps:ApplyDownload", + "Webapps:Uninstall"].indexOf(aMessage.name) != -1) { if (!aMessage.target.assertPermission("webapps-manage")) { debug("mozApps message " + aMessage.name + " from a content process with no 'webapps-manage' privileges."); @@ -837,6 +838,7 @@ this.DOMApplicationRegistry = { // Webapps:RemoveApp // Webapps:Install:Return:OK // Webapps:Uninstall:Return:OK + // Webapps:Uninstall:Broadcast:Return:OK // Webapps:OfflineCache // Webapps:checkForUpdate:Return:OK // Webapps:PackageEvent @@ -2145,7 +2147,8 @@ this.DOMApplicationRegistry = { this._saveApps((function() { aData.manifestURL = app.manifestURL; - this.broadcastMessage("Webapps:Uninstall:Return:OK", aData); + this.broadcastMessage("Webapps:Uninstall:Broadcast:Return:OK", aData); + aMm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData); Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote); this.broadcastMessage("Webapps:RemoveApp", { id: id }); }).bind(this)); @@ -2359,8 +2362,8 @@ this.DOMApplicationRegistry = { dir.remove(true); } catch (e) { } - this.broadcastMessage("Webapps:Uninstall:Return:OK", { origin: origin, - manifestURL: manifestURL }); + this.broadcastMessage("Webapps:Uninstall:Broadcast:Return:OK", + { origin: origin, manifestURL: manifestURL }); } else { if (this.webapps[record.id]) { this.webapps[record.id] = record.value; diff --git a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl index 05933d3d4614..aa69418aa0a6 100644 --- a/dom/interfaces/apps/nsIDOMApplicationRegistry.idl +++ b/dom/interfaces/apps/nsIDOMApplicationRegistry.idl @@ -8,7 +8,7 @@ interface nsIDOMDOMRequest; interface nsIDOMDOMError; -[scriptable, uuid(84524e5f-c4ab-4dce-8364-4aac71851ff1)] +[scriptable, uuid(d89870fe-5ba3-11e2-a5d2-cfa1d3f6e5f4)] interface mozIDOMApplication : nsISupports { readonly attribute jsval manifest; @@ -84,13 +84,12 @@ interface mozIDOMApplication : nsISupports /* startPoint will be used when several launch_path exists for an app */ nsIDOMDOMRequest launch([optional] in DOMString startPoint); - nsIDOMDOMRequest uninstall(); /* Clear data that has been collected through mozbrowser elements. */ void clearBrowserData(); }; -[scriptable, uuid(0015d114-70c1-44ae-a8a3-fb6c107fe0e1)] +[scriptable, uuid(cf742022-5ba3-11e2-868f-03310341b006)] interface mozIDOMApplicationMgmt : nsISupports { /** @@ -125,6 +124,15 @@ interface mozIDOMApplicationMgmt : nsISupports * |readyToApplyDownload| set to true. */ void applyDownload(in mozIDOMApplication app); + + /** + * Uninstall a web app. + * + * @param app : the app object of the web app to be uninstalled. + * @returns : A DOMRequest object, returning the app's origin in |result| + * if uninstall succeeds; returning "NOT_INSTALLED" error otherwise. + */ + nsIDOMDOMRequest uninstall(in mozIDOMApplication app); }; [scriptable, uuid(abfc6c15-8b92-4b9a-b892-52e6ae76f379)]