--- a/dom/apps/PermissionsTable.jsm
+++ b/dom/apps/PermissionsTable.jsm
@@ -30,398 +30,470 @@ const PROMPT_ACTION = Ci.nsIPermissionMa
// Permissions Matrix: https://docs.google.com/spreadsheet/ccc?key=0Akyz_Bqjgf5pdENVekxYRjBTX0dCXzItMnRyUU1RQ0E#gid=0
// Permissions that are implicit:
// battery-status, network-information, vibration,
// device-capabilities
this.PermissionsTable = { geolocation: {
app: PROMPT_ACTION,
+ trusted: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: PROMPT_ACTION
},
"geolocation-noprompt": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
substitute: ["geolocation"]
},
camera: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION
},
alarms: {
app: ALLOW_ACTION,
+ trusted: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"tcp-socket": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"udp-socket": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"network-events": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
contacts: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:apps": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read"]
},
"device-storage:crashes": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read"]
},
"device-storage:pictures": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:videos": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:music": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"device-storage:sdcard": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
sms: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
telephony: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
browser: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
bluetooth: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
mobileconnection: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
mobilenetwork: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
power: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
push: {
app: ALLOW_ACTION,
+ trusted: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
settings: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write"],
additional: ["indexedDB-chrome-settings", "settings-api"]
},
// This exists purely for tests, no app
// should ever use it. It can only be
// handed out by SpecialPowers.
"settings-clear": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: DENY_ACTION,
additional: ["indexedDB-chrome-settings", "settings-api"]
},
permissions: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
phonenumberservice: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
fmradio: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
attention: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-attention": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
substitute: ["attention"]
},
"webapps-manage": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"backgroundservice": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"desktop-notification": {
app: ALLOW_ACTION,
+ trusted: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"networkstats-manage": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"resourcestats-manage": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"wifi-manage": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"systemXHR": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"voicemail": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"deprecated-hwvideo": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"idle": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"time": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"embed-apps": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"embed-widgets": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"storage": {
app: ALLOW_ACTION,
+ trusted: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
substitute: [
"indexedDB-unlimited",
"default-persistent-storage"
]
},
"background-sensors": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
cellbroadcast: {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-normal": {
app: ALLOW_ACTION,
+ trusted: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-content": {
app: ALLOW_ACTION,
+ trusted: ALLOW_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-notification": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-alarm": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"audio-channel-telephony": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-audio-channel-telephony": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
substitute: ["audio-channel-telephony"]
},
"audio-channel-ringer": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-audio-channel-ringer": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION,
substitute: ["audio-channel-ringer"]
},
"audio-channel-publicnotification": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"open-remote-window": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"input": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"input-manage": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"wappush": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"audio-capture": {
app: PROMPT_ACTION,
+ trusted: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION
},
"nfc": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write"]
},
"nfc-manager": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"nfc-hci-events": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"speaker-control": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"downloads": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"video-capture": {
app: PROMPT_ACTION,
+ trusted: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION
},
"feature-detection": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
"mobileid": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: PROMPT_ACTION
},
// This permission doesn't actually grant access to
// anything. It exists only to check the correctness
// of web prompt composed permissions in tests.
"test-permission": {
app: PROMPT_ACTION,
+ trusted: PROMPT_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write", "create"]
},
"firefox-accounts": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"moz-firefox-accounts": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
substitute: ["firefox-accounts"]
},
"themeable": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
},
"settings:wallpaper.image": {
app: DENY_ACTION,
+ trusted: DENY_ACTION,
privileged: PROMPT_ACTION,
certified: ALLOW_ACTION,
access: ["read", "write"],
additional: ["settings-api"]
}
};
/**
--- a/dom/apps/Webapps.jsm
+++ b/dom/apps/Webapps.jsm
@@ -150,16 +150,17 @@ XPCOMUtils.defineLazyGetter(this, "updat
// store even by error.
const STORE_ID_PENDING_PREFIX = "#unknownID#";
this.DOMApplicationRegistry = {
// pseudo-constants for the different application kinds.
get kPackaged() "packaged",
get kHosted() "hosted",
get kHostedAppcache() "hosted-appcache",
+ get kTrustedHosted() "hosted-trusted",
// Path to the webapps.json file where we store the registry data.
appsFile: null,
webapps: { },
children: [ ],
allAppsLaunchable: false,
_updateHandlers: [ ],
_pendingUninstalls: {},
@@ -366,23 +367,17 @@ this.DOMApplicationRegistry = {
app.role = aResult.manifest.role || "";
let localeManifest = new ManifestHelper(aResult.manifest, app.origin, app.manifestURL);
this._saveWidgetsFullPath(localeManifest, app);
if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
app.redirects = this.sanitizeRedirects(aResult.redirects);
}
- if (app.origin.startsWith("app://")) {
- app.kind = this.kPackaged;
- } else {
- // Hosted apps, can be appcached or not.
- app.kind = aResult.manifest.appcache_path ? this.kHostedAppcache
- : this.kHosted;
- }
+ app.kind = this.appKind(app, aResult.manifest);
});
// Nothing else to do but notifying we're ready.
this.notifyAppsRegistryReady();
}
}),
updateDataStoreForApp: Task.async(function*(aId) {
@@ -392,33 +387,49 @@ this.DOMApplicationRegistry = {
// Create or Update the DataStore for this app
let results = yield this._readManifests([{ id: aId }]);
let app = this.webapps[aId];
this.updateDataStore(app.localId, app.origin, app.manifestURL,
results[0].manifest, app.appStatus);
}),
+ appKind: function(aApp, aManifest) {
+ if (aApp.origin.startsWith("app://")) {
+ return this.kPackaged;
+ } else {
+ // Hosted apps, can be appcached or not.
+ let kind = this.kHosted;
+ if (aManifest.type == "trusted") {
+ kind = this.kTrustedHosted;
+ } else if (aManifest.appcache_path) {
+ kind = this.kHostedAppcache;
+ }
+ return kind;
+ }
+ },
+
updatePermissionsForApp: function(aId, aIsPreinstalled, aIsSystemUpdate) {
if (!this.webapps[aId]) {
return;
}
// Install the permissions for this app, as if we were updating
// to cleanup the old ones if needed.
// TODO It's not clear what this should do when there are multiple profiles.
if (supportUseCurrentProfile()) {
this._readManifests([{ id: aId }]).then((aResult) => {
let data = aResult[0];
PermissionsInstaller.installPermissions({
manifest: data.manifest,
manifestURL: this.webapps[aId].manifestURL,
origin: this.webapps[aId].origin,
isPreinstalled: aIsPreinstalled,
- isSystemUpdate: aIsSystemUpdate
+ isSystemUpdate: aIsSystemUpdate,
+ kind: this.webapps[aId].kind
}, true, function() {
debug("Error installing permissions for " + aId);
});
});
}
},
updateOfflineCacheForApp: function(aId) {
@@ -1011,23 +1022,17 @@ this.DOMApplicationRegistry = {
app.name = manifest.name;
app.csp = manifest.csp || "";
app.role = localeManifest.role;
this._saveWidgetsFullPath(localeManifest, app);
if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
app.redirects = this.sanitizeRedirects(manifest.redirects);
}
- if (app.origin.startsWith("app://")) {
- app.kind = this.kPackaged;
- } else {
- // Hosted apps, can be appcached or not.
- app.kind = aResult.manifest.appcache_path ? this.kHostedAppcache
- : this.kHosted;
- }
+ app.kind = this.appKind(app, aResult.manifest);
this._registerSystemMessages(manifest, app);
this._registerInterAppConnections(manifest, app);
appsToRegister.push({ manifest: manifest, app: app });
});
this._safeToClone.resolve();
this._registerActivitiesForApps(appsToRegister, aRunUpdate);
});
},
@@ -1673,36 +1678,41 @@ this.DOMApplicationRegistry = {
let appObject = AppsUtils.cloneAppObject(app);
appObject.updateManifest = updateManifest;
this.notifyUpdateHandlers(appObject, newManifest, appFile.path);
if (supportUseCurrentProfile()) {
PermissionsInstaller.installPermissions(
{ manifest: newManifest,
origin: app.origin,
- manifestURL: app.manifestURL },
+ manifestURL: app.manifestURL,
+ kind: app.kind },
true);
}
this.updateDataStore(this.webapps[id].localId, app.origin,
app.manifestURL, newManifest);
this.broadcastMessage("Webapps:UpdateState", {
app: app,
manifest: newManifest,
id: app.id
});
this.broadcastMessage("Webapps:FireEvent", {
eventType: "downloadapplied",
manifestURL: app.manifestURL
});
}),
startOfflineCacheDownload: function(aManifest, aApp, aProfileDir, aIsUpdate) {
- if (aApp.kind !== this.kHostedAppcache) {
+ debug("startOfflineCacheDownload " + aApp.id + " " + aApp.kind);
+ if ((aApp.kind !== this.kHostedAppcache &&
+ aApp.kind !== this.kTrustedHosted) ||
+ !aManifest.appcache_path) {
return;
}
+ debug("startOfflineCacheDownload " + aManifest.appcache_path);
// If the manifest has an appcache_path property, use it to populate the
// appcache.
let appcacheURI = Services.io.newURI(aManifest.fullAppcachePath(),
null, null);
let docURI = Services.io.newURI(aManifest.fullLaunchPath(), null, null);
// We determine the app's 'installState' according to its previous
@@ -1815,25 +1825,30 @@ this.DOMApplicationRegistry = {
#ifdef MOZ_WIDGET_GONK
let appDir = FileUtils.getDir("coreAppsDir", ["webapps"], false);
onlyCheckAppCache = (app.basePath == appDir.path);
#endif
if (onlyCheckAppCache) {
// Bail out for packaged apps & hosted apps without appcache.
- if (app.kind !== this.kHostedAppcache) {
+ if (aApp.kind !== this.kHostedAppcache &&
+ aApp.kind !== this.kTrustedHosted) {
sendError("NOT_UPDATABLE");
return;
}
// We need the manifest to get the appcache path.
this._readManifests([{ id: id }]).then((aResult) => {
debug("Checking only appcache for " + aData.manifestURL);
let manifest = aResult[0].manifest;
+ if (!manifest.appcache_path) {
+ sendError("NOT_UPDATABLE");
+ return;
+ }
// Check if the appcache is updatable, and send "downloadavailable" or
// "downloadapplied".
let updateObserver = {
observe: function(aSubject, aTopic, aObsData) {
debug("onlyCheckAppCache updateSvc.checkForUpdate return for " +
app.manifestURL + " - event is " + aTopic);
if (aTopic == "offline-cache-update-available") {
app.downloadAvailable = true;
@@ -2105,34 +2120,37 @@ this.DOMApplicationRegistry = {
manifest =
new ManifestHelper(aNewManifest, aApp.origin, aApp.manifestURL);
if (supportUseCurrentProfile()) {
// Update the permissions for this app.
PermissionsInstaller.installPermissions({
manifest: aApp.manifest,
origin: aApp.origin,
- manifestURL: aData.manifestURL
+ manifestURL: aData.manifestURL,
+ kind: aApp.kind
}, true);
}
this.updateDataStore(this.webapps[aId].localId, aApp.origin,
aApp.manifestURL, aApp.manifest);
aApp.name = aNewManifest.name;
aApp.csp = manifest.csp || "";
this._saveWidgetsFullPath(manifest, aApp);
aApp.updateTime = Date.now();
}
// Update the registry.
this.webapps[aId] = aApp;
yield this._saveApps();
- if (aApp.kind !== this.kHostedAppcache) {
+ if ((aApp.kind !== this.kHostedAppcache &&
+ aApp.kind !== this.kTrustedHosted) ||
+ !aApp.manifest.appcache_path) {
this.broadcastMessage("Webapps:UpdateState", {
app: aApp,
manifest: aApp.manifest,
id: aApp.id
});
this.broadcastMessage("Webapps:FireEvent", {
eventType: "downloadapplied",
manifestURL: aApp.manifestURL,
@@ -2198,17 +2216,18 @@ this.DOMApplicationRegistry = {
}
}
}
// Hosted apps can't be trusted or certified, so just check that the
// manifest doesn't ask for those.
function checkAppStatus(aManifest) {
let manifestStatus = aManifest.type || "web";
- return manifestStatus === "web";
+ return manifestStatus === "web" ||
+ manifestStatus === "trusted";
}
let checkManifest = (function() {
if (!app.manifest) {
sendError("MANIFEST_PARSE_ERROR");
return false;
}
@@ -2490,29 +2509,35 @@ this.DOMApplicationRegistry = {
return app;
},
_cloneApp: function(aData, aNewApp, aLocaleManifest, aManifest, aId, aLocalId) {
let appObject = AppsUtils.cloneAppObject(aNewApp);
appObject.appStatus =
aNewApp.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
- if (appObject.kind == this.kHostedAppcache) {
+ let usesAppcache = appObject.kind == this.kHostedAppcache;
+ if (appObject.kind == this.kTrustedHosted && aManifest.appcache_path) {
+ usesAppcache = true;
+ }
+
+ if (usesAppcache) {
appObject.installState = "pending";
appObject.downloadAvailable = true;
appObject.downloading = true;
appObject.downloadSize = 0;
appObject.readyToApplyDownload = false;
} else if (appObject.kind == this.kPackaged) {
appObject.installState = "pending";
appObject.downloadAvailable = true;
appObject.downloading = true;
appObject.downloadSize = aLocaleManifest.size;
appObject.readyToApplyDownload = false;
- } else if (appObject.kind == this.kHosted) {
+ } else if (appObject.kind == this.kHosted ||
+ appObject.kind == this.kTrustedHosted) {
appObject.installState = "installed";
appObject.downloadAvailable = false;
appObject.downloading = false;
appObject.readyToApplyDownload = false;
} else {
debug("Unknown app kind: " + appObject.kind);
throw Error("Unknown app kind: " + appObject.kind);
}
@@ -2644,35 +2669,32 @@ this.DOMApplicationRegistry = {
let jsonManifest = aData.isPackage ? app.updateManifest : app.manifest;
yield this._writeManifestFile(id, aData.isPackage, jsonManifest);
debug("app.origin: " + app.origin);
let manifest =
new ManifestHelper(jsonManifest, app.origin, app.manifestURL);
// Set the application kind.
- if (aData.isPackage) {
- app.kind = this.kPackaged;
- } else {
- app.kind = manifest.appcache_path ? this.kHostedAppcache : this.kHosted;
- }
+ app.kind = this.appKind(app, manifest);
let appObject = this._cloneApp(aData, app, manifest, jsonManifest, id, localId);
this.webapps[id] = appObject;
// For package apps, the permissions are not in the mini-manifest, so
// don't update the permissions yet.
if (!aData.isPackage) {
if (supportUseCurrentProfile()) {
PermissionsInstaller.installPermissions(
{
origin: appObject.origin,
manifestURL: appObject.manifestURL,
- manifest: jsonManifest
+ manifest: jsonManifest,
+ kind: appObject.kind
},
isReinstall,
this.doUninstall.bind(this, aData, aData.mm)
);
}
this.updateDataStore(this.webapps[id].localId, this.webapps[id].origin,
this.webapps[id].manifestURL, jsonManifest);
@@ -2680,17 +2702,19 @@ this.DOMApplicationRegistry = {
for each (let prop in ["installState", "downloadAvailable", "downloading",
"downloadSize", "readyToApplyDownload"]) {
aData.app[prop] = appObject[prop];
}
let dontNeedNetwork = false;
- if (appObject.kind == this.kHostedAppcache) {
+ if ((appObject.kind == this.kHostedAppcache ||
+ appObject.kind == this.kTrustedHosted) &&
+ manifest.appcache_path) {
this.queuedDownload[app.manifestURL] = {
manifest: manifest,
app: appObject,
profileDir: aProfileDir
}
} else if (appObject.kind == this.kPackaged) {
// If it is a local app then it must been installed from a local file
// instead of web.
@@ -2810,17 +2834,18 @@ this.DOMApplicationRegistry = {
Services.obs.notifyObservers(null, "webapps-installed",
JSON.stringify({ manifestURL: aNewApp.manifestURL }));
if (supportUseCurrentProfile()) {
// Update the permissions for this app.
PermissionsInstaller.installPermissions({
manifest: aManifest,
origin: aNewApp.origin,
- manifestURL: aNewApp.manifestURL
+ manifestURL: aNewApp.manifestURL,
+ kind: this.webapps[aId].kind
}, true);
}
this.updateDataStore(this.webapps[aId].localId, aNewApp.origin,
aNewApp.manifestURL, aManifest);
if (aInstallSuccessCallback) {
try {