michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "FreeSpaceWatcher", michael@0: "resource://gre/modules/FreeSpaceWatcher.jsm"); michael@0: michael@0: this.EXPORTED_SYMBOLS = ["AppDownloadManager"]; michael@0: michael@0: function debug(aMsg) { michael@0: //dump("-*-*- AppDownloadManager.jsm : " + aMsg + "\n"); michael@0: } michael@0: michael@0: this.AppDownloadManager = { michael@0: // Minimum disk free space we want to keep, in bytes. michael@0: // Keep synchronized with Webapps.jsm michael@0: MIN_REMAINING_FREESPACE: 5 * 1024 * 1024, michael@0: michael@0: downloads: {}, michael@0: count: 0, michael@0: cancelFunc: null, michael@0: timer: null, michael@0: michael@0: /** michael@0: * Registers the function called when we need to cancel a download. michael@0: * The function will be called with a single parameter being the michael@0: * manifest URL. michael@0: */ michael@0: registerCancelFunction: function app_dlMgr_registerCancel(aFunction) { michael@0: this.cancelFunc = aFunction; michael@0: }, michael@0: michael@0: /** michael@0: * Adds a download to the list of current downloads. michael@0: * @param aManifestURL The manifest URL for the application being downloaded. michael@0: * @param aDownload An opaque object representing the download. michael@0: */ michael@0: add: function app_dlMgr_add(aManifestURL, aDownload) { michael@0: debug("Adding " + aManifestURL); michael@0: if (!(aManifestURL in this.downloads)) { michael@0: this.count++; michael@0: if (this.count == 1) { michael@0: this.timer = FreeSpaceWatcher.create(this.MIN_REMAINING_FREESPACE, michael@0: this._spaceWatcher.bind(this)); michael@0: } michael@0: } michael@0: this.downloads[aManifestURL] = aDownload; michael@0: }, michael@0: michael@0: /** michael@0: * Retrieves a download from the list of current downloads. michael@0: * @param aManifestURL The manifest URL for the application being retrieved. michael@0: * @return The opaque object representing the download. michael@0: */ michael@0: get: function app_dlMgr_get(aManifestURL) { michael@0: debug("Getting " + aManifestURL); michael@0: if (!this.downloads[aManifestURL]) { michael@0: return null; michael@0: } michael@0: return this.downloads[aManifestURL]; michael@0: }, michael@0: michael@0: /** michael@0: * Removes a download of the list of current downloads. michael@0: * @param aManifestURL The manifest URL for the application being removed. michael@0: */ michael@0: remove: function app_dlMgr_remove(aManifestURL) { michael@0: debug("Removing " + aManifestURL); michael@0: if (aManifestURL in this.downloads) { michael@0: this.count--; michael@0: delete this.downloads[aManifestURL]; michael@0: if (this.count == 0) { michael@0: FreeSpaceWatcher.stop(this.timer); michael@0: } michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Callback for the free space watcher. This will call cancel on downloads michael@0: * if needed. michael@0: */ michael@0: _spaceWatcher: function app_dlMgr_watcher(aStatus) { michael@0: debug("Disk space is now " + aStatus); michael@0: if (aStatus == "free") { michael@0: // Nothing to do. michael@0: return; michael@0: } michael@0: michael@0: // We cancel all downloads, because we don't know which ones we could michael@0: // keep running. We can improve that later if we have better heuristics, michael@0: // or when we'll support pause & resume we should just pause downloads. michael@0: for (let url in this.downloads) { michael@0: this.cancelFunc(url, "INSUFFICIENT_STORAGE"); michael@0: } michael@0: } michael@0: }