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)
this.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");
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 + " )");
if (this.inParent) {
return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
} else {
return this.cpmm.sendSyncMessage("WebApps:GetAppByManifestURL",
{ url: aManifestURL })[0];
}
},
getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aManifestURL) {
debug("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 + " )");
if (this.inParent) {
return DOMApplicationRegistry.getAppByLocalId(aLocalId);
} else {
return this.cpmm.sendSyncMessage("WebApps:GetAppByLocalId",
{ id: aLocalId })[0];
}
},
getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
debug("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

@ -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)
@ -120,9 +112,6 @@ WebappsRegistry.prototype = {
let manifest = JSON.parse(xhr.responseText, installOrigin);
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 : [];
@ -136,7 +125,6 @@ WebappsRegistry.prototype = {
oid: this._id,
requestID: requestID });
}
}
} catch(e) {
Services.DOMRequest.fireError(request, "MANIFEST_PARSE_ERROR");
}

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,7 +50,6 @@ XPCOMUtils.defineLazyGetter(this, "msgmgr", function() {
let DOMApplicationRegistry = {
appsFile: null,
webapps: { },
children: [ ],
allAppsLaunchable: false,
init: function() {
@ -60,7 +58,8 @@ let DOMApplicationRegistry = {
"Webapps:GetInstalled", "Webapps:GetNotInstalled",
"Webapps:Launch", "Webapps:GetAll",
"Webapps:InstallPackage", "Webapps:GetBasePath",
"Webapps:GetList"];
"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;
@ -350,9 +366,6 @@ let DOMApplicationRegistry = {
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);