diff -r 000000000000 -r 6474c204b198 dom/apps/src/AppDownloadManager.jsm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/apps/src/AppDownloadManager.jsm Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,104 @@ +/* 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 Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "FreeSpaceWatcher", + "resource://gre/modules/FreeSpaceWatcher.jsm"); + +this.EXPORTED_SYMBOLS = ["AppDownloadManager"]; + +function debug(aMsg) { + //dump("-*-*- AppDownloadManager.jsm : " + aMsg + "\n"); +} + +this.AppDownloadManager = { + // Minimum disk free space we want to keep, in bytes. + // Keep synchronized with Webapps.jsm + MIN_REMAINING_FREESPACE: 5 * 1024 * 1024, + + downloads: {}, + count: 0, + cancelFunc: null, + timer: null, + + /** + * Registers the function called when we need to cancel a download. + * The function will be called with a single parameter being the + * manifest URL. + */ + registerCancelFunction: function app_dlMgr_registerCancel(aFunction) { + this.cancelFunc = aFunction; + }, + + /** + * Adds a download to the list of current downloads. + * @param aManifestURL The manifest URL for the application being downloaded. + * @param aDownload An opaque object representing the download. + */ + add: function app_dlMgr_add(aManifestURL, aDownload) { + debug("Adding " + aManifestURL); + if (!(aManifestURL in this.downloads)) { + this.count++; + if (this.count == 1) { + this.timer = FreeSpaceWatcher.create(this.MIN_REMAINING_FREESPACE, + this._spaceWatcher.bind(this)); + } + } + this.downloads[aManifestURL] = aDownload; + }, + + /** + * Retrieves a download from the list of current downloads. + * @param aManifestURL The manifest URL for the application being retrieved. + * @return The opaque object representing the download. + */ + get: function app_dlMgr_get(aManifestURL) { + debug("Getting " + aManifestURL); + if (!this.downloads[aManifestURL]) { + return null; + } + return this.downloads[aManifestURL]; + }, + + /** + * Removes a download of the list of current downloads. + * @param aManifestURL The manifest URL for the application being removed. + */ + remove: function app_dlMgr_remove(aManifestURL) { + debug("Removing " + aManifestURL); + if (aManifestURL in this.downloads) { + this.count--; + delete this.downloads[aManifestURL]; + if (this.count == 0) { + FreeSpaceWatcher.stop(this.timer); + } + } + }, + + /** + * Callback for the free space watcher. This will call cancel on downloads + * if needed. + */ + _spaceWatcher: function app_dlMgr_watcher(aStatus) { + debug("Disk space is now " + aStatus); + if (aStatus == "free") { + // Nothing to do. + return; + } + + // We cancel all downloads, because we don't know which ones we could + // keep running. We can improve that later if we have better heuristics, + // or when we'll support pause & resume we should just pause downloads. + for (let url in this.downloads) { + this.cancelFunc(url, "INSUFFICIENT_STORAGE"); + } + } +}