diff --git a/lib/offline/download_manager.js b/lib/offline/download_manager.js index d6a6ffc7db..a80a34212d 100644 --- a/lib/offline/download_manager.js +++ b/lib/offline/download_manager.js @@ -75,6 +75,9 @@ shaka.offline.DownloadManager = class { /** @private {shaka.offline.DownloadProgressEstimator} */ this.estimator_ = new shaka.offline.DownloadProgressEstimator(); + + /** @private {boolean} */ + this.aborted_ = false; } /** @override */ @@ -97,11 +100,19 @@ shaka.offline.DownloadManager = class { * aborted. */ abortAll() { + this.aborted_ = true; const promises = this.abortCallbacks_.map((callback) => callback()); this.abortCallbacks_ = []; return Promise.all(promises); } + /** + * @return {boolean} + */ + isAborted() { + return this.aborted_; + } + /** * Adds a byte length to the download estimate. * diff --git a/lib/offline/storage.js b/lib/offline/storage.js index 76f0ba7d6b..49fee309f3 100644 --- a/lib/offline/storage.js +++ b/lib/offline/storage.js @@ -521,12 +521,22 @@ shaka.offline.Storage = class { let pendingManifestUpdates = {}; let pendingDataSize = 0; + const ensureNotAbortedOrDestroyed = () => { + if (this.destroyer_.destroyed() || downloader.isAborted()) { + throw new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.STORAGE, + shaka.util.Error.Code.OPERATION_ABORTED); + } + }; + /** * @param {!Array.} toDownload * @param {boolean} updateDRM */ const download = async (toDownload, updateDRM) => { for (const download of toDownload) { + ensureNotAbortedOrDestroyed(); const request = download.makeSegmentRequest(config); const estimateId = download.estimateId; const isInitSegment = download.isInitSegment; @@ -541,7 +551,7 @@ shaka.offline.Storage = class { } // Store the data. const dataKeys = await storage.addSegments([{data}]); - this.ensureNotDestroyed_(); + ensureNotAbortedOrDestroyed(); // Store the necessary update to the manifest, to be processed later. pendingManifestUpdates[id] = dataKeys[0]; @@ -560,14 +570,14 @@ shaka.offline.Storage = class { } } await downloader.waitToFinish(); + ensureNotAbortedOrDestroyed(); - if (updateDRM) { + if (updateDRM && !downloader.isAborted()) { // Re-store the manifest, to attach session IDs. // These were (maybe) discovered inside the downloader; we can only add // them now, at the end, since the manifestDB is in flux during the // process of downloading and storing, and assignSegmentsToManifest // does not know about the DRM engine. - this.ensureNotDestroyed_(); this.setManifestDrmFields_( manifest, manifestDB, drmEngine, usePersistentLicense); await storage.updateManifest(manifestId, manifestDB); @@ -583,7 +593,7 @@ shaka.offline.Storage = class { // init data from the init segments, download those first before // anything else. await download(toDownload.filter((info) => info.isInitSegment), true); - this.ensureNotDestroyed_(); + ensureNotAbortedOrDestroyed(); toDownload = toDownload.filter((info) => !info.isInitSegment); // Copy these and reset them now, before calling await. @@ -595,12 +605,12 @@ shaka.offline.Storage = class { await shaka.offline.Storage.assignSegmentsToManifest( storage, manifestId, manifestDB, manifestUpdates, dataSize, () => this.ensureNotDestroyed_()); - this.ensureNotDestroyed_(); + ensureNotAbortedOrDestroyed(); } if (!usingBgFetch) { await download(toDownload, false); - this.ensureNotDestroyed_(); + ensureNotAbortedOrDestroyed(); // Copy these and reset them now, before calling await. const manifestUpdates = pendingManifestUpdates; @@ -610,8 +620,8 @@ shaka.offline.Storage = class { await shaka.offline.Storage.assignSegmentsToManifest( storage, manifestId, manifestDB, manifestUpdates, dataSize, - () => this.ensureNotDestroyed_()); - this.ensureNotDestroyed_(); + () => ensureNotAbortedOrDestroyed()); + ensureNotAbortedOrDestroyed(); goog.asserts.assert( !manifestDB.isIncomplete, 'The manifest should be complete by now');