mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-28 16:41:52 +00:00
Bug 702369 - ensure that web app install caches them into app cache on B2G [r=jonas,vingtetun,felipe]
This commit is contained in:
parent
7079a51003
commit
f5ff57a3d4
@ -37,8 +37,8 @@ function convertAppsArray(aApps, aWindow) {
|
||||
let apps = Cu.createArrayIn(aWindow);
|
||||
for (let i = 0; i < aApps.length; i++) {
|
||||
let app = aApps[i];
|
||||
apps.push(new WebappsApplication(aWindow, app.origin, app.manifest, app.manifestURL,
|
||||
app.receipts, app.installOrigin, app.installTime));
|
||||
apps.push(createApplicationObject(aWindow, app.origin, app.manifest, app.manifestURL,
|
||||
app.receipts, app.installOrigin, app.installTime));
|
||||
}
|
||||
|
||||
return apps;
|
||||
@ -49,6 +49,12 @@ function WebappsRegistry() {
|
||||
|
||||
WebappsRegistry.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
__exposedProps__: {
|
||||
install: 'r',
|
||||
getSelf: 'r',
|
||||
getInstalled: 'r',
|
||||
mgmt: 'r'
|
||||
},
|
||||
|
||||
/** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest
|
||||
* only the name property is mandatory
|
||||
@ -76,8 +82,8 @@ WebappsRegistry.prototype = {
|
||||
let app = msg.app;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install:Return:OK":
|
||||
Services.DOMRequest.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
break;
|
||||
case "Webapps:Install:Return:KO":
|
||||
Services.DOMRequest.fireError(req, "DENIED");
|
||||
@ -85,8 +91,8 @@ WebappsRegistry.prototype = {
|
||||
case "Webapps:GetSelf:Return:OK":
|
||||
if (msg.apps.length) {
|
||||
app = msg.apps[0];
|
||||
Services.DOMRequest.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
} else {
|
||||
Services.DOMRequest.fireSuccess(req, null);
|
||||
}
|
||||
@ -200,63 +206,57 @@ WebappsRegistry.prototype = {
|
||||
/**
|
||||
* mozIDOMApplication object
|
||||
*/
|
||||
function WebappsApplication(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
|
||||
this._origin = aOrigin;
|
||||
this._manifestURL = aManifestURL;
|
||||
this._manifest = wrapObjectIn(aManifest, aWindow);
|
||||
this._receipts = aReceipts;
|
||||
this._installOrigin = aInstallOrigin;
|
||||
this._installTime = aInstallTime;
|
||||
|
||||
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO"]);
|
||||
function createApplicationObject(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
|
||||
let app = Cc["@mozilla.org/webapps/application;1"].createInstance(Ci.mozIDOMApplication);
|
||||
app.wrappedJSObject.init(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime);
|
||||
return app;
|
||||
}
|
||||
|
||||
function WebappsApplication() {
|
||||
this.wrappedJSObject = this;
|
||||
}
|
||||
|
||||
WebappsApplication.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
_origin: null,
|
||||
_manifest: null,
|
||||
_manifestURL: null,
|
||||
_receipts: [],
|
||||
_installOrigin: null,
|
||||
_installTime: 0,
|
||||
__exposedProps__: {
|
||||
origin: 'r',
|
||||
manifest: 'r',
|
||||
manifestURL: 'r',
|
||||
installOrigin: 'r',
|
||||
installTime: 'r',
|
||||
status: 'r',
|
||||
progress: 'r',
|
||||
onprogress: 'rw',
|
||||
launch: 'r',
|
||||
receipts: 'r',
|
||||
uninstall: 'r'
|
||||
},
|
||||
|
||||
get origin() {
|
||||
return this._origin;
|
||||
init: function(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
|
||||
this.origin = aOrigin;
|
||||
this.manifest = wrapObjectIn(aManifest, aWindow);
|
||||
this.manifestURL = aManifestURL;
|
||||
this.receipts = aReceipts;
|
||||
this.installOrigin = aInstallOrigin;
|
||||
this.installTime = aInstallTime;
|
||||
this.status = "installed";
|
||||
this.progress = NaN;
|
||||
this._onprogress = null;
|
||||
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO", "Webapps:OfflineCache"]);
|
||||
},
|
||||
|
||||
get manifest() {
|
||||
return this._manifest;
|
||||
set onprogress(aCallback) {
|
||||
this._onprogress = aCallback;
|
||||
},
|
||||
|
||||
get manifestURL() {
|
||||
return this._manifestURL;
|
||||
},
|
||||
|
||||
get receipts() {
|
||||
return this._receipts;
|
||||
},
|
||||
|
||||
get installOrigin() {
|
||||
return this._installOrigin;
|
||||
},
|
||||
|
||||
get installTime() {
|
||||
return this._installTime;
|
||||
get onprogress() {
|
||||
return this._onprogress;
|
||||
},
|
||||
|
||||
launch: function(aStartPoint) {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this._origin,
|
||||
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this.origin,
|
||||
startPoint: aStartPoint || "",
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
@ -265,16 +265,20 @@ WebappsApplication.prototype = {
|
||||
|
||||
uninstall: function() {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this._origin,
|
||||
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this.origin,
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
return request;
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this._onprogress = null;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
var msg = aMessage.json;
|
||||
let req = this.getRequest(msg.requestID);
|
||||
if (msg.oid != this._id || !req)
|
||||
let req = this.takeRequest(msg.requestID);
|
||||
if ((msg.oid != this._id || !req) && aMessage.name !== "Webapps:OfflineCache")
|
||||
return;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Uninstall:Return:OK":
|
||||
@ -283,8 +287,17 @@ WebappsApplication.prototype = {
|
||||
case "Webapps:Uninstall:Return:KO":
|
||||
Services.DOMRequest.fireError(req, "NOT_INSTALLED");
|
||||
break;
|
||||
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 });
|
||||
this._onprogress.handleEvent(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.removeRequest(msg.requestID);
|
||||
},
|
||||
|
||||
classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
|
||||
@ -321,6 +334,11 @@ function WebappsApplicationMgmt(aWindow) {
|
||||
|
||||
WebappsApplicationMgmt.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
__exposedProps__: {
|
||||
getAll: 'r',
|
||||
oninstall: 'rw',
|
||||
onuninstall: 'rw'
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this._oninstall = null;
|
||||
@ -376,7 +394,7 @@ WebappsApplicationMgmt.prototype = {
|
||||
if (this._oninstall) {
|
||||
let app = msg.app;
|
||||
let event = new this._window.MozApplicationEvent("applicationinstall",
|
||||
{ application : new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
{ application : createApplicationObject(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime) });
|
||||
this._oninstall.handleEvent(event);
|
||||
}
|
||||
@ -384,7 +402,7 @@ WebappsApplicationMgmt.prototype = {
|
||||
case "Webapps:Uninstall:Return:OK":
|
||||
if (this._onuninstall) {
|
||||
let event = new this._window.MozApplicationEvent("applicationuninstall",
|
||||
{ application : new WebappsApplication(this._window, msg.origin, null, null, null, null, 0) });
|
||||
{ application : createApplicationObject(this._window, msg.origin, null, null, null, null, 0) });
|
||||
this._onuninstall.handleEvent(event);
|
||||
}
|
||||
break;
|
||||
|
@ -156,7 +156,9 @@ let DOMApplicationRegistry = {
|
||||
origin: aApp.origin,
|
||||
receipts: aApp.receipts,
|
||||
installTime: aApp.installTime,
|
||||
manifestURL: aApp.manifestURL
|
||||
manifestURL: aApp.manifestURL,
|
||||
progress: aApp.progress || 0.0,
|
||||
status: aApp.status || "installed"
|
||||
};
|
||||
return clone;
|
||||
},
|
||||
@ -165,7 +167,7 @@ let DOMApplicationRegistry = {
|
||||
ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
|
||||
},
|
||||
|
||||
confirmInstall: function(aData, aFromSync) {
|
||||
confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
|
||||
let app = aData.app;
|
||||
let id = app.syncId || this._appId(app.origin);
|
||||
|
||||
@ -191,11 +193,29 @@ let DOMApplicationRegistry = {
|
||||
this._writeFile(manFile, JSON.stringify(app.manifest));
|
||||
this.webapps[id] = appObject;
|
||||
|
||||
appObject.status = "installed";
|
||||
|
||||
let manifest = new DOMApplicationManifest(app.manifest, app.origin);
|
||||
|
||||
if (!aFromSync)
|
||||
this._saveApps((function() {
|
||||
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
|
||||
Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
|
||||
}).bind(this));
|
||||
|
||||
// if the manifest has an appcache_path property, use it to populate the appcache
|
||||
if (manifest.appcache_path) {
|
||||
let appcacheURI = Services.io.newURI(manifest.fullAppcachePath(), null, null);
|
||||
let updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"]
|
||||
.getService(Ci.nsIOfflineCacheUpdateService);
|
||||
let docURI = Services.io.newURI(manifest.fullLaunchPath(), null, null);
|
||||
let cacheUpdate = aProfileDir ? updateService.scheduleCustomProfileUpdate(appcacheURI, docURI, aProfileDir)
|
||||
: updateService.scheduleUpdate(appcacheURI, docURI, null);
|
||||
cacheUpdate.addObserver(new AppcacheObserver(appObject), false);
|
||||
if (aOfflineCacheObserver) {
|
||||
cacheUpdate.addObserver(aOfflineCacheObserver, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_appId: function(aURI) {
|
||||
@ -428,6 +448,53 @@ let DOMApplicationRegistry = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Appcache download observer
|
||||
*/
|
||||
AppcacheObserver = function(aApp) {
|
||||
this.app = aApp;
|
||||
};
|
||||
|
||||
AppcacheObserver.prototype = {
|
||||
// nsIOfflineCacheUpdateObserver implementation
|
||||
updateStateChanged: function appObs_Update(aUpdate, aState) {
|
||||
let mustSave = false;
|
||||
let app = this.app;
|
||||
|
||||
let setStatus = function appObs_setStatus(aStatus) {
|
||||
mustSave = (app.status != aStatus);
|
||||
app.status = aStatus;
|
||||
ppmm.sendAsyncMessage("Webapps:OfflineCache", { manifest: app.manifestURL, status: aStatus });
|
||||
}
|
||||
|
||||
switch (aState) {
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
|
||||
aUpdate.removeObserver(this);
|
||||
setStatus("cache-error");
|
||||
break;
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED:
|
||||
aUpdate.removeObserver(this);
|
||||
setStatus("cached");
|
||||
break;
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_DOWNLOADING:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMPROGRESS:
|
||||
setStatus("downloading")
|
||||
break;
|
||||
}
|
||||
|
||||
// Status changed, update the stored version.
|
||||
if (mustSave) {
|
||||
DOMApplicationRegistry._saveApps();
|
||||
}
|
||||
},
|
||||
|
||||
applicationCacheAvailable: function appObs_CacheAvail(aApplicationCache) {
|
||||
// Nothing to do.
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper object to access manifest information with locale support
|
||||
*/
|
||||
@ -481,6 +548,10 @@ DOMApplicationManifest.prototype = {
|
||||
return this._localeProp("icons");
|
||||
},
|
||||
|
||||
get appcache_path() {
|
||||
return this._localeProp("appcache_path");
|
||||
},
|
||||
|
||||
iconURLForSize: function(aSize) {
|
||||
let icons = this._localeProp("icons");
|
||||
if (!icons)
|
||||
@ -501,6 +572,11 @@ DOMApplicationManifest.prototype = {
|
||||
let startPoint = aStartPoint || "";
|
||||
let launchPath = this._localeProp("launch_path") || "";
|
||||
return this._origin.resolve(launchPath + startPoint);
|
||||
},
|
||||
|
||||
fullAppcachePath: function() {
|
||||
let appcachePath = this._localeProp("appcache_path");
|
||||
return this._origin.resolve(appcachePath ? appcachePath : "");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,3 +2,6 @@
|
||||
component {fff440b3-fae2-45c1-bf03-3b5a2e432270} Webapps.js
|
||||
contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270}
|
||||
category JavaScript-navigator-property mozApps @mozilla.org/webapps;1
|
||||
|
||||
component {723ed303-7757-4fb0-b261-4f78b1f6bd22} Webapps.js
|
||||
contract @mozilla.org/webapps/application;1 {723ed303-7757-4fb0-b261-4f78b1f6bd22}
|
||||
|
@ -9,15 +9,34 @@
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIArray;
|
||||
|
||||
[scriptable, uuid(b70b84f1-7ac9-4a92-bc32-8b6a7eb7879e)]
|
||||
[scriptable, uuid(9583b825-46b1-4e8f-bb48-9fed660a95e6)]
|
||||
interface mozIDOMApplication : nsISupports
|
||||
{
|
||||
readonly attribute jsval manifest;
|
||||
readonly attribute DOMString manifestURL;
|
||||
readonly attribute nsIArray receipts; /* an array of strings */
|
||||
readonly attribute jsval receipts; /* an array of strings */
|
||||
readonly attribute DOMString origin;
|
||||
readonly attribute DOMString installOrigin;
|
||||
readonly attribute unsigned long installTime;
|
||||
readonly attribute unsigned long long installTime;
|
||||
|
||||
/*
|
||||
* The current progress when downloading an offline cache.
|
||||
*/
|
||||
readonly attribute double progress;
|
||||
|
||||
/*
|
||||
* The application status :
|
||||
* "installed" : The app is in the registry, but we have no offline cache.
|
||||
* "downlading" : We are downloading the offline cache.
|
||||
* "cached" : We are done with the offline cache download.
|
||||
* "cache-error" : An error occured while downloading the offline-cache.
|
||||
*/
|
||||
readonly attribute DOMString status;
|
||||
|
||||
/*
|
||||
* fires a nsIDOMApplicationEvent when a change in appcache download or status happens
|
||||
*/
|
||||
attribute nsIDOMEventListener onprogress;
|
||||
|
||||
/* startPoint will be used when several launch_path exists for an app */
|
||||
nsIDOMDOMRequest launch([optional] in DOMString startPoint);
|
||||
|
Loading…
x
Reference in New Issue
Block a user