author | Fernando Jiménez <ferjmoreno@gmail.com> |
Thu, 15 Nov 2012 10:35:37 +0100 | |
changeset 113371 | d95d4e953df5cec58abbf8116fe0b4be1f9acf60 |
parent 113370 | c6188b322a68fc4e6bb3e8bd2ed0cecd3c6c1b7b |
child 113372 | cbe5fc3e1ce5dd9f2039fd1827bbdcc6885b2906 |
push id | 23869 |
push user | emorley@mozilla.com |
push date | Thu, 15 Nov 2012 16:18:16 +0000 |
treeherder | mozilla-central@a37525d304d9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | fabrice |
bugs | 809948 |
milestone | 19.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/apps/src/Webapps.js | file | annotate | diff | comparison | revisions | |
dom/apps/src/Webapps.jsm | file | annotate | diff | comparison | revisions |
--- a/dom/apps/src/Webapps.js +++ b/dom/apps/src/Webapps.js @@ -574,17 +574,17 @@ WebappsApplication.prototype = { case "installed": let app = msg.app; this.progress = app.progress || 0; this.downloadAvailable = app.downloadAvailable; this.downloading = app.downloading; this.readyToApplyDownload = app.readyToApplyDownload; this.downloadSize = app.downloadSize || 0; this.installState = app.installState; - this.manifest = app.manifest; + this._manifest = msg.manifest; this._fireEvent("downloadsuccess", this._ondownloadsuccess); this._fireEvent("downloadapplied", this._ondownloadapplied); break; case "canceled": app = msg.app; this.progress = app.progress || 0; this.downloadAvailable = app.downloadAvailable; this.downloading = app.downloading;
--- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -1295,27 +1295,28 @@ this.DOMApplicationRegistry = { // - add the new app to the registry. // If we fail at any step, we backout the previous ones and return an error. debug(JSON.stringify(aApp)); let id = this._appIdForManifestURL(aApp.manifestURL); let app = this.webapps[id]; + let self = this; // Removes the directory we created, and sends an error to the DOM side. function cleanup(aError) { debug("Cleanup: " + aError); let dir = FileUtils.getDir("TmpD", ["webapps", id], true, true); try { dir.remove(true); } catch (e) { } - this.broadcastMessage("Webapps:PackageEvent", + self.broadcastMessage("Webapps:PackageEvent", { type: "error", manifestURL: aApp.manifestURL, - error: aError}); + error: aError }); } function getInferedStatus() { // XXX Update once we have digital signatures (bug 772365) return Ci.nsIPrincipal.APP_STATUS_INSTALLED; } function getAppStatus(aManifest) { @@ -1330,104 +1331,129 @@ this.DOMApplicationRegistry = { function checkAppStatus(aManifest) { if (Services.prefs.getBoolPref("dom.mozApps.dev_mode")) { return true; } return (AppsUtils.getAppManifestStatus(aManifest) <= getInferedStatus()); } - debug("About to download " + aManifest.fullPackagePath()); + function download() { + debug("About to download " + aManifest.fullPackagePath()); + + let requestChannel = NetUtil.newChannel(aManifest.fullPackagePath()) + .QueryInterface(Ci.nsIHttpChannel); + self.downloads[aApp.manifestURL] = + { channel:requestChannel, + appId: id, + previousState: aIsUpdate ? "installed" : "pending" + }; + requestChannel.notificationCallbacks = { + QueryInterface: function notifQI(aIID) { + if (aIID.equals(Ci.nsISupports) || + aIID.equals(Ci.nsIProgressEventSink)) + return this; - let requestChannel = NetUtil.newChannel(aManifest.fullPackagePath()) - .QueryInterface(Ci.nsIHttpChannel); - this.downloads[aApp.manifestURL] = - { channel:requestChannel, - appId: id, - previousState: aIsUpdate ? "installed" : "pending" - }; - requestChannel.notificationCallbacks = { - QueryInterface: function notifQI(aIID) { - if (aIID.equals(Ci.nsISupports) || - aIID.equals(Ci.nsIProgressEventSink)) - return this; + throw Cr.NS_ERROR_NO_INTERFACE; + }, + getInterface: function notifGI(aIID) { + return this.QueryInterface(aIID); + }, + onProgress: function notifProgress(aRequest, aContext, + aProgress, aProgressMax) { + debug("onProgress: " + aProgress + "/" + aProgressMax); + app.progress = aProgress; + self.broadcastMessage("Webapps:PackageEvent", + { type: "progress", + manifestURL: aApp.manifestURL, + progress: aProgress }); + }, + onStatus: function notifStatus(aRequest, aContext, aStatus, aStatusArg) { } + } + NetUtil.asyncFetch(requestChannel, + function(aInput, aResult, aRequest) { + if (!Components.isSuccessCode(aResult)) { + // We failed to fetch the zip. + cleanup("NETWORK_ERROR"); + return; + } + // Copy the zip on disk. + let zipFile = FileUtils.getFile("TmpD", + ["webapps", id, "application.zip"], true); + let ostream = FileUtils.openSafeFileOutputStream(zipFile); + NetUtil.asyncCopy(aInput, ostream, function (aResult) { + if (!Components.isSuccessCode(aResult)) { + // We failed to save the zip. + cleanup("DOWNLOAD_ERROR"); + return; + } - throw Cr.NS_ERROR_NO_INTERFACE; - }, - getInterface: function notifGI(aIID) { - return this.QueryInterface(aIID); - }, - onProgress: function notifProgress(aRequest, aContext, - aProgress, aProgressMax) { - debug("onProgress: " + aProgress + "/" + aProgressMax); - app.progress = aProgress; - DOMApplicationRegistry.broadcastMessage("Webapps:PackageEvent", - { type: "progress", - manifestURL: aApp.manifestURL, - progress: aProgress }); - }, - onStatus: function notifStatus(aRequest, aContext, aStatus, aStatusArg) { } - } + let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] + .createInstance(Ci.nsIZipReader); + try { + zipReader.open(zipFile); + if (!zipReader.hasEntry("manifest.webapp")) { + throw "No manifest.webapp found."; + } + + let istream = zipReader.getInputStream("manifest.webapp"); + + // Obtain a converter to read from a UTF-8 encoded input stream. + let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let manifest = JSON.parse(converter.ConvertToUnicode(NetUtil.readInputStreamToString(istream, + istream.available()) || "")); + + if (!AppsUtils.checkManifest(manifest, aApp.installOrigin)) { + throw "INVALID_MANIFEST"; + } - NetUtil.asyncFetch(requestChannel, - function(aInput, aResult, aRequest) { - if (!Components.isSuccessCode(aResult)) { - // We failed to fetch the zip. - cleanup("NETWORK_ERROR"); + if (!checkAppStatus(manifest)) { + throw "INVALID_SECURITY_LEVEL"; + } + + if (aOnSuccess) { + aOnSuccess(id, manifest); + } + delete self.downloads[aApp.manifestURL]; + } catch (e) { + // XXX we may need new error messages. + cleanup(e); + } finally { + zipReader.close(); + } + }); + }); + }; + + let browser = Services.wm.getMostRecentWindow("navigator:browser"); + let deviceStorage = browser.getContentWindow().navigator + .getDeviceStorage("apps"); + let req = deviceStorage.stat(); + req.onsuccess = req.onerror = function statResult(e) { + // Even if we could not retrieve the device storage free space, we try + // to download the package. + if (!e.target.result) { + download(); return; } - // Copy the zip on disk. - let zipFile = FileUtils.getFile("TmpD", - ["webapps", id, "application.zip"], true); - let ostream = FileUtils.openSafeFileOutputStream(zipFile); - NetUtil.asyncCopy(aInput, ostream, function (aResult) { - if (!Components.isSuccessCode(aResult)) { - // We failed to save the zip. - cleanup("DOWNLOAD_ERROR"); + + let freeBytes = e.target.result.freeBytes; + if (freeBytes) { + debug("Free storage: " + freeBytes + ". Download size: " + + aApp.downloadSize); + if (freeBytes <= aApp.downloadSize) { + cleanup("INSUFFICIENT_STORAGE"); return; } - - let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] - .createInstance(Ci.nsIZipReader); - try { - zipReader.open(zipFile); - if (!zipReader.hasEntry("manifest.webapp")) { - throw "No manifest.webapp found."; - } - - let istream = zipReader.getInputStream("manifest.webapp"); - - // Obtain a converter to read from a UTF-8 encoded input stream. - let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] - .createInstance(Ci.nsIScriptableUnicodeConverter); - converter.charset = "UTF-8"; - - let manifest = JSON.parse(converter.ConvertToUnicode(NetUtil.readInputStreamToString(istream, - istream.available()) || "")); - - if (!AppsUtils.checkManifest(manifest, aApp.installOrigin)) { - throw "INVALID_MANIFEST"; - } - - if (!checkAppStatus(manifest)) { - throw "INVALID_SECURITY_LEVEL"; - } - - if (aOnSuccess) { - aOnSuccess(id, manifest); - } - delete DOMApplicationRegistry.downloads[aApp.manifestURL]; - } catch (e) { - // XXX we may need new error messages. - cleanup(e); - } finally { - zipReader.close(); - } - }); - }); + } + download(); + } }, uninstall: function(aData, aMm) { for (let id in this.webapps) { let app = this.webapps[id]; if (app.origin != aData.origin) { continue; }