Back out a08d28e8a86b (bug 768868), 9b96029a9cf0 and 010b5cb3576d (bug 781620) for test failures and leaks

This commit is contained in:
Phil Ringnalda 2012-08-27 21:34:53 -07:00
parent 79b6b7fa0b
commit b8d45a9ae2
9 changed files with 158 additions and 359 deletions

View File

@ -30,9 +30,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/HashFunctions.h"
#include "nsIAppsService.h"
#include "mozIApplication.h"
using namespace mozilla;
static bool gCodeBasePrincipalSupport = false;
@ -1302,45 +1299,10 @@ nsPrincipal::GetAppStatus()
// Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
// and they are not inside a mozbrowser.
if (mAppId == nsIScriptSecurityManager::NO_APP_ID ||
mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID || mInMozBrowser) {
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(appsService, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsCOMPtr<mozIDOMApplication> domApp;
appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
NS_ENSURE_TRUE(app, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
uint16_t status = nsIPrincipal::APP_STATUS_INSTALLED;
NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsCAutoString origin;
NS_ENSURE_SUCCESS(GetOrigin(getter_Copies(origin)),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsString appOrigin;
NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
// We go from string -> nsIURI -> origin to be sure we
// compare two punny-encoded origins.
nsCOMPtr<nsIURI> appURI;
NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
nsCAutoString appOriginPunned;
NS_ENSURE_SUCCESS(GetOriginForURI(appURI, getter_Copies(appOriginPunned)),
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
if (!appOriginPunned.Equals(origin)) {
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
}
return status;
return mAppId != nsIScriptSecurityManager::NO_APP_ID &&
mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID && !mInMozBrowser
? nsIPrincipal::APP_STATUS_INSTALLED
: nsIPrincipal::APP_STATUS_NOT_INSTALLED;
}
/************************************************************************************************************************/

View File

@ -5,7 +5,7 @@
"use strict"
function debug(s) {
//dump("-*- AppsService.js: " + s + "\n");
//dump("-*- AppsService: " + s + "\n");
}
const Cc = Components.classes;
@ -19,32 +19,57 @@ const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}")
function AppsService()
{
debug("AppsService Constructor");
let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
debug("inParent: " + inParent);
Cu.import(inParent ? "resource://gre/modules/Webapps.jsm" :
"resource://gre/modules/AppsServiceChild.jsm");
this.inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
debug("inParent: " + this.inParent);
if (this.inParent) {
Cu.import("resource://gre/modules/Webapps.jsm");
} else {
this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
.getService(Ci.nsISyncMessageSender);
}
}
AppsService.prototype = {
getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
debug("GetAppByManifestURL( " + aManifestURL + " )");
return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
if (this.inParent) {
return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
} else {
return this.cpmm.sendSyncMessage("WebApps:GetAppByManifestURL",
{ url: aManifestURL })[0];
}
},
getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aManifestURL) {
debug("getAppLocalIdByManifestURL( " + aManifestURL + " )");
return DOMApplicationRegistry.getAppLocalIdByManifestURL(aManifestURL);
if (this.inParent) {
return DOMApplicationRegistry.getAppLocalIdByManifestURL(aManifestURL);
} else {
let res = this.cpmm.sendSyncMessage("WebApps:GetAppLocalIdByManifestURL",
{ url: aManifestURL })[0];
return res.id;
}
},
getAppByLocalId: function getAppByLocalId(aLocalId) {
debug("getAppByLocalId( " + aLocalId + " )");
return DOMApplicationRegistry.getAppByLocalId(aLocalId);
if (this.inParent) {
return DOMApplicationRegistry.getAppByLocalId(aLocalId);
} else {
return this.cpmm.sendSyncMessage("WebApps:GetAppByLocalId",
{ id: aLocalId })[0];
}
},
getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
debug("getManifestURLByLocalId( " + aLocalId + " )");
return DOMApplicationRegistry.getManifestURLByLocalId(aLocalId);
if (this.inParent) {
return DOMApplicationRegistry.getManifestURLByLocalId(aLocalId);
} else {
return this.cpmm.sendSyncMessage("WebApps:GetManifestURLByLocalId",
{ id: aLocalId })[0];
}
},
classID : APPS_SERVICE_CID,

View File

@ -1,71 +0,0 @@
/* 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 Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
// This module exposes a subset of the functionnalities of the parent DOM
// Registry to content processes, to be be used from the AppsService component.
let EXPORTED_SYMBOLS = ["DOMApplicationRegistry"];
Cu.import("resource://gre/modules/AppsUtils.jsm");
function debug(s) {
//dump("-*- AppsServiceChild.jsm: " + s + "\n");
}
let DOMApplicationRegistry = {
init: function init() {
debug("init");
this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
.getService(Ci.nsISyncMessageSender);
["Webapps:AddApp", "Webapps:RemoveApp"].forEach((function(aMsgName) {
this.cpmm.addMessageListener(aMsgName, this);
}).bind(this));
// We need to prime the cache with the list of apps.
// XXX shoud we do this async and block callers if it's not yet there?
this.webapps = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
},
receiveMessage: function receiveMessage(aMessage) {
debug("Received " + aMessage.name + " message.");
let msg = aMessage.json;
switch (aMessage.name) {
case "Webapps:AddApp":
this.webapps[msg.id] = msg.app;
break;
case "Webapps:RemoveApp":
delete this.webapps[msg.id];
break;
}
},
getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
debug("getAppByManifestURL " + aManifestURL);
return AppsUtils.getAppByManifestURL(this.webapps, aManifestURL);
},
getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aManifestURL) {
debug("getAppLocalIdByManifestURL " + aManifestURL);
return AppsUtils.getAppLocalIdByManifestURL(this.webapps, aManifestURL);
},
getAppByLocalId: function getAppByLocalId(aLocalId) {
debug("getAppByLocalId " + aLocalId);
return AppsUtils.getAppByLocalId(this.webapps, aLocalId);
},
getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
debug("getManifestURLByLocalId " + aLocalId);
return AppsUtils.getManifestURLByLocalId(this.webapps, aLocalId);
}
}
DOMApplicationRegistry.init();

View File

@ -1,108 +0,0 @@
/* 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 Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
// Shared code for AppsServiceChild.jsm and Webapps.jsm
let EXPORTED_SYMBOLS = ["AppsUtils"];
function debug(s) {
//dump("-*- AppsUtils.jsm: " + s + "\n");
}
let AppsUtils = {
// Clones a app, without the manifest.
cloneAppObject: function cloneAppObject(aApp) {
return {
installOrigin: aApp.installOrigin,
origin: aApp.origin,
receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
installTime: aApp.installTime,
manifestURL: aApp.manifestURL,
appStatus: aApp.appStatus,
localId: aApp.localId,
progress: aApp.progress || 0.0,
status: aApp.status || "installed"
};
},
cloneAsMozIApplication: function cloneAsMozIApplication(aApp) {
let res = this.cloneAppObject(aApp);
res.hasPermission = function(aPermission) {
let uri = Services.io.newURI(this.origin, null, null);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
// This helper checks an URI inside |aApp|'s origin and part of |aApp| has a
// specific permission. It is not checking if browsers inside |aApp| have such
// permission.
let principal = secMan.getAppCodebasePrincipal(uri, aApp.localId,
/*mozbrowser*/false);
let perm = Services.perms.testExactPermissionFromPrincipal(principal,
aPermission);
return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
};
res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
Ci.mozIApplication]);
return res;
},
getAppByManifestURL: function getAppByManifestURL(aApps, aManifestURL) {
debug("getAppByManifestURL " + aManifestURL);
// This could be O(1) if |webapps| was a dictionary indexed on manifestURL
// which should be the unique app identifier.
// It's currently O(n).
for (let id in aApps) {
let app = aApps[id];
if (app.manifestURL == aManifestURL) {
return this.cloneAsMozIApplication(app);
}
}
return null;
},
getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aApps, aManifestURL) {
debug("getAppLocalIdByManifestURL " + aManifestURL);
for (let id in aApps) {
if (aApps[id].manifestURL == aManifestURL) {
return aApps[id].localId;
}
}
return Ci.nsIScriptSecurityManager.NO_APP_ID;
},
getAppByLocalId: function getAppByLocalId(aApps, aLocalId) {
debug("getAppByLocalId " + aLocalId);
for (let id in aApps) {
let app = aApps[id];
if (app.localId == aLocalId) {
return this.cloneAsMozIApplication(app);
}
}
return null;
},
getManifestURLByLocalId: function getManifestURLByLocalId(aApps, aLocalId) {
debug("getManifestURLByLocalId " + aLocalId);
for (let id in aApps) {
let app = aApps[id];
if (app.localId == aLocalId) {
return app.manifestURL;
}
}
return "";
}
}

View File

@ -18,8 +18,6 @@ EXTRA_COMPONENTS = \
EXTRA_PP_JS_MODULES += \
Webapps.jsm \
AppsServiceChild.jsm \
AppsUtils.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -20,7 +20,7 @@ function convertAppsArray(aApps, aWindow) {
let apps = Cu.createArrayIn(aWindow);
for (let i = 0; i < aApps.length; i++) {
let app = aApps[i];
apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
app.receipts, app.installOrigin, app.installTime));
}
@ -55,14 +55,6 @@ WebappsRegistry.prototype = {
return true;
},
// Hosted apps can't be trusted or certified, so just check that the
// manifest doesn't ask for those.
checkAppStatus: function(aManifest) {
let manifestStatus = aManifest.type || "web";
return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") ||
manifestStatus === "web");
},
receiveMessage: function(aMessage) {
let msg = aMessage.json;
if (msg.oid != this._id)
@ -100,11 +92,11 @@ WebappsRegistry.prototype = {
_getOrigin: function(aURL) {
let uri = Services.io.newURI(aURL, null, null);
return uri.prePath;
return uri.prePath;
},
// mozIDOMApplicationRegistry implementation
install: function(aURL, aParams) {
let installURL = this._window.location.href;
let installOrigin = this._getOrigin(installURL);
@ -121,21 +113,17 @@ WebappsRegistry.prototype = {
if (!this.checkManifest(manifest, installOrigin)) {
Services.DOMRequest.fireError(request, "INVALID_MANIFEST");
} else {
if (!this.checkAppStatus(manifest)) {
Services.DOMRequest.fireError(request, "INVALID_SECURITY_LEVEL");
} else {
let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : [];
cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
origin: this._getOrigin(aURL),
manifestURL: aURL,
manifest: manifest,
receipts: receipts,
categories: categories },
from: installURL,
oid: this._id,
requestID: requestID });
}
let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
let categories = (aParams && aParams.categories && Array.isArray(aParams.categories)) ? aParams.categories : [];
cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
origin: this._getOrigin(aURL),
manifestURL: aURL,
manifest: manifest,
receipts: receipts,
categories: categories },
from: installURL,
oid: this._id,
requestID: requestID });
}
} catch(e) {
Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR");
@ -143,7 +131,7 @@ WebappsRegistry.prototype = {
}
else {
Services.DOMRequest.fireError(request, "MANIFEST_URL_ERROR");
}
}
}).bind(this), false);
xhr.addEventListener("error", (function() {
@ -207,11 +195,11 @@ WebappsRegistry.prototype = {
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this._id = util.outerWindowID;
},
classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry, Ci.nsIDOMGlobalPropertyInitializer]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
contractID: "@mozilla.org/webapps;1",
interfaces: [Ci.mozIDOMApplicationRegistry],
@ -306,7 +294,7 @@ WebappsApplication.prototype = {
case "Webapps:OfflineCache":
if (msg.manifest != this.manifestURL)
return;
this.status = msg.status;
if (this._onprogress) {
let event = new this._window.MozApplicationEvent("applicationinstall", { application: this });
@ -405,7 +393,7 @@ WebappsApplicationMgmt.prototype = {
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)
if (!((msg.oid == this._id && req)
|| aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
return;
switch (aMessage.name) {
@ -421,7 +409,7 @@ WebappsApplicationMgmt.prototype = {
case "Webapps:Install:Return:OK":
if (this._oninstall) {
let app = msg.app;
let event = new this._window.MozApplicationEvent("applicationinstall",
let event = new this._window.MozApplicationEvent("applicationinstall",
{ application : createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
app.installOrigin, app.installTime) });
this._oninstall.handleEvent(event);
@ -429,7 +417,7 @@ WebappsApplicationMgmt.prototype = {
break;
case "Webapps:Uninstall:Return:OK":
if (this._onuninstall) {
let event = new this._window.MozApplicationEvent("applicationuninstall",
let event = new this._window.MozApplicationEvent("applicationuninstall",
{ application : createApplicationObject(this._window, msg.origin, null, null, null, null, 0) });
this._onuninstall.handleEvent(event);
}

View File

@ -15,7 +15,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import('resource://gre/modules/ActivitiesService.jsm');
Cu.import("resource://gre/modules/AppsUtils.jsm");
const WEBAPP_RUNTIME = Services.appinfo.ID == "webapprt@mozilla.org";
@ -51,16 +50,16 @@ XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
let DOMApplicationRegistry = {
appsFile: null,
webapps: { },
children: [ ],
allAppsLaunchable: false,
init: function() {
this.messages = ["Webapps:Install", "Webapps:Uninstall",
"Webapps:GetSelf",
"Webapps:GetInstalled", "Webapps:GetNotInstalled",
"Webapps:Launch", "Webapps:GetAll",
"Webapps:InstallPackage", "Webapps:GetBasePath",
"Webapps:GetList"];
"Webapps:GetSelf",
"Webapps:GetInstalled", "Webapps:GetNotInstalled",
"Webapps:Launch", "Webapps:GetAll",
"Webapps:InstallPackage", "Webapps:GetBasePath",
"WebApps:GetAppByManifestURL", "WebApps:GetAppLocalIdByManifestURL",
"WebApps:GetAppByLocalId", "WebApps:GetManifestURLByLocalId"];
this.messages.forEach((function(msgName) {
ppmm.addMessageListener(msgName, this);
@ -81,11 +80,6 @@ let DOMApplicationRegistry = {
if (!this.webapps[id].localId) {
this.webapps[id].localId = this._nextLocalId();
}
// Default to a non privileged status.
if (this.webapps[id].appStatus === undefined) {
this.webapps[id].appStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
}
};
}).bind(this));
}
@ -256,9 +250,18 @@ let DOMApplicationRegistry = {
case "Webapps:GetBasePath":
return FileUtils.getFile(DIRECTORY_NAME, ["webapps"], true).path;
break;
case "Webapps:GetList":
this.children.push(aMessage.target);
return this.webapps;
case "WebApps:GetAppByManifestURL":
return this.getAppByManifestURL(msg.url);
break;
case "WebApps:GetAppLocalIdByManifestURL":
return { id: this.getAppLocalIdByManifestURL(msg.url) };
break;
case "WebApps:GetAppByLocalId":
return this.getAppByLocalId(msg.id);
break;
case "WebApps:GetManifestURLByLocalId":
return this.getManifestURLByLocalId(msg.id);
break;
}
},
@ -279,6 +282,20 @@ let DOMApplicationRegistry = {
});
},
// clones a app object, without the manifest
_cloneAppObject: function(aApp) {
let clone = {
installOrigin: aApp.installOrigin,
origin: aApp.origin,
receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
installTime: aApp.installTime,
manifestURL: aApp.manifestURL,
progress: aApp.progress || 0.0,
status: aApp.status || "installed"
};
return clone;
},
denyInstall: function(aData) {
let packageId = aData.app.packageId;
if (packageId) {
@ -314,8 +331,7 @@ let DOMApplicationRegistry = {
app.origin = "app://" + id;
}
let appObject = AppsUtils.cloneAppObject(app);
appObject.appStatus = app.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
let appObject = this._cloneAppObject(app);
appObject.installTime = app.installTime = Date.now();
let appNote = JSON.stringify(appObject);
appNote.id = id;
@ -329,10 +345,10 @@ let DOMApplicationRegistry = {
// If this a packaged app, move the zip file from the temp directory,
// and delete the temp directory.
if (app.packageId) {
let appFile = FileUtils.getFile("TmpD", ["webapps", app.packageId, "application.zip"],
let appFile = FileUtils.getFile("TmpD", ["webapps", app.packageId, "application.zip"],
true, true);
appFile.moveTo(dir, "application.zip");
let tmpDir = FileUtils.getDir("TmpD", ["webapps", app.packageId],
let tmpDir = FileUtils.getDir("TmpD", ["webapps", app.packageId],
true, true);
try {
tmpDir.remove(true);
@ -343,16 +359,13 @@ let DOMApplicationRegistry = {
this.webapps[id] = appObject;
appObject.status = "installed";
let manifest = new DOMApplicationManifest(app.manifest, app.origin);
if (!aFromSync)
this._saveApps((function() {
ppmm.broadcastAsyncMessage("Webapps:Install:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
this.children.forEach(function(aMsgMgr) {
aMsgMgr.broadcastAsyncMessage("Webapps:AddApp", { id: id, app: appObject });
});
}).bind(this));
#ifdef MOZ_SYS_MSG
@ -484,47 +497,6 @@ let DOMApplicationRegistry = {
error: aError });
}
function getInferedStatus() {
// XXX Update once we have digital signatures (bug 772365)
return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
}
function getAppManifestStatus(aManifest) {
let type = aManifest.type || "web";
let manifestStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
switch(type) {
case "web":
manifestStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
break;
case "privileged":
manifestStatus = Ci.nsIPrincipal.APP_STATUS_PRIVILEGED;
break
case "certified":
manifestStatus = Ci.nsIPrincipal.APP_STATUS_CERTIFIED;
break;
}
return manifestStatus;
}
function getAppStatus(aManifest) {
let manifestStatus = getAppManifestStatus(aManifest);
let inferedStatus = getInferedStatus();
return (Services.prefs.getBoolPref("dom.mozApps.dev_mode") ? manifestStatus
: inferedStatus);
}
// Returns true if the privilege level from the manifest
// is lower or equal to the one we infered for the app.
function checkAppStatus(aManifest) {
if (Services.prefs.getBoolPref("dom.mozApps.dev_mode")) {
return true;
}
return (getAppManifestStatus(aManifest) <= getInferedStatus());
}
NetUtil.asyncFetch(aData.url, function(aInput, aResult, aRequest) {
if (!Components.isSuccessCode(aResult)) {
// We failed to fetch the zip.
@ -570,19 +542,14 @@ let DOMApplicationRegistry = {
msg.app.manifest = JSON.parse(NetUtil.readInputStreamToString(istream,
istream.available()) || "");
if (!checkManifest(msg.app.manifest)) {
throw "INVALID_MANIFEST";
throw "Invalid manifest";
}
if (!checkAppStatus(msg.app.manifest)) {
throw "INVALID_SECURITY_LEVEL";
}
msg.appStatus = getAppStatus(msg.app.manifest);
Services.obs.notifyObservers(this, "webapps-ask-install",
JSON.stringify(msg));
} catch (e) {
// XXX we may need new error messages.
cleanup(e);
cleanup("INVALID_MANIFEST");
} finally {
zipReader.close();
}
@ -599,7 +566,7 @@ let DOMApplicationRegistry = {
}
found = true;
let appNote = JSON.stringify(AppsUtils.cloneAppObject(app));
let appNote = JSON.stringify(this._cloneAppObject(app));
appNote.id = id;
this._readManifests([{ id: id }], (function unregisterManifest(aResult) {
@ -618,9 +585,6 @@ let DOMApplicationRegistry = {
this._saveApps((function() {
ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:OK", aData);
Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
this.children.forEach(function(aMsgMgr) {
aMsgMgr.broadcastAsyncMessage("Webapps:RemoveApp", { id: id });
});
}).bind(this));
}
@ -635,7 +599,7 @@ let DOMApplicationRegistry = {
let id = this._appId(aData.origin);
if (id && this._isLaunchable(this.webapps[id].origin)) {
let app = AppsUtils.cloneAppObject(this.webapps[id]);
let app = this._cloneAppObject(this.webapps[id]);
aData.apps.push(app);
tmp.push({ id: id });
}
@ -654,7 +618,7 @@ let DOMApplicationRegistry = {
for (let id in this.webapps) {
if (this.webapps[id].installOrigin == aData.origin &&
this._isLaunchable(this.webapps[id].origin)) {
aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
aData.apps.push(this._cloneAppObject(this.webapps[id]));
tmp.push({ id: id });
}
}
@ -672,7 +636,7 @@ let DOMApplicationRegistry = {
for (let id in this.webapps) {
if (!this._isLaunchable(this.webapps[id].origin)) {
aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
aData.apps.push(this._cloneAppObject(this.webapps[id]));
tmp.push({ id: id });
}
}
@ -689,7 +653,7 @@ let DOMApplicationRegistry = {
let tmp = [];
for (let id in this.webapps) {
let app = AppsUtils.cloneAppObject(this.webapps[id]);
let app = this._cloneAppObject(this.webapps[id]);
if (!this._isLaunchable(app.origin))
continue;
@ -728,30 +692,78 @@ let DOMApplicationRegistry = {
if (!this.webapps[aId])
return null;
let app = AppsUtils.cloneAppObject(this.webapps[aId]);
let app = this._cloneAppObject(this.webapps[aId]);
return app;
},
getAppByManifestURL: function(aManifestURL) {
return AppsUtils.getAppByManifestURL(this.webapps, aManifestURL);
// This could be O(1) if |webapps| was a dictionary indexed on manifestURL
// which should be the unique app identifier.
// It's currently O(n).
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.manifestURL == aManifestURL) {
let res = this._cloneAppObject(app);
res.hasPermission = function(permission) {
let localId = DOMApplicationRegistry.getAppLocalIdByManifestURL(
this.manifestURL);
let uri = Services.io.newURI(this.manifestURL, null, null);
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
// XXX for the purposes of permissions checking, this helper
// should always be called on !isBrowser frames, so we
// assume false here.
let principal = secMan.getAppCodebasePrincipal(uri, localId,
/*mozbrowser*/false);
let perm = Services.perms.testExactPermissionFromPrincipal(principal,
permission);
return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
};
res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
Ci.mozIApplication]);
return res;
}
}
return null;
},
getAppByLocalId: function(aLocalId) {
return AppsUtils.getAppByLocalId(this.webapps, aLocalId);
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.localId == aLocalId) {
return this._cloneAppObject(app);
}
}
return null;
},
getManifestURLByLocalId: function(aLocalId) {
return AppsUtils.getManifestURLByLocalId(this.webapps, aLocalId);
for (let id in this.webapps) {
let app = this.webapps[id];
if (app.localId == aLocalId) {
return app.manifestURL;
}
}
return null;
},
getAppLocalIdByManifestURL: function(aManifestURL) {
return AppsUtils.getAppLocalIdByManifestURL(this.webapps, aManifestURL);
for (let id in this.webapps) {
if (this.webapps[id].manifestURL == aManifestURL) {
return this.webapps[id].localId;
}
}
return Ci.nsIScriptSecurityManager.NO_APP_ID;
},
getAllWithoutManifests: function(aCallback) {
let result = {};
for (let id in this.webapps) {
let app = AppsUtils.cloneAppObject(this.webapps[id]);
let app = this._cloneAppObject(this.webapps[id]);
result[id] = app;
}
aCallback(result);

View File

@ -11,12 +11,9 @@
* We expose Gecko-internal helpers related to "web apps" through this
* sub-interface.
*/
[scriptable, uuid(acf46a46-729a-4ab4-9da3-8d59ecfd103d)]
[scriptable, uuid(8de25e36-b4cb-4e89-9310-a199dce4e5f4)]
interface mozIApplication: mozIDOMApplication
{
/* Return true if this app has |permission|. */
boolean hasPermission(in string permission);
/* Application status as defined in nsIPrincipal. */
readonly attribute unsigned short appStatus;
};

View File

@ -3689,7 +3689,3 @@ pref("social.enabled", false);
// Disable idle observer fuzz, because only privileged content can access idle
// observers (bug 780507).
pref("dom.idle-observers-api.fuzz_time.disabled", true);
// Setting that to true grant elevated privileges to apps that ask
// for them in their manifest.
pref("dom.mozApps.dev_mode", false);