Bug 830415 - Part 2 - Move the front-end code that stores download metadata in history to the DownloadHistory module. r=mak
Regression tests will be added in
bug 1381411 when methods to retrieve the metadata will be available.
MozReview-Commit-ID: I3MgwM0EOty
--- a/browser/components/downloads/DownloadsCommon.jsm
+++ b/browser/components/downloads/DownloadsCommon.jsm
@@ -42,28 +42,28 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppMenuNotifications",
"resource://gre/modules/AppMenuNotifications.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
"resource:///modules/CustomizableUI.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "DownloadHistory",
+ "resource://gre/modules/DownloadHistory.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
"resource://gre/modules/Downloads.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DownloadUIHelper",
"resource://gre/modules/DownloadUIHelper.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
"resource://gre/modules/DownloadUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
- "resource://gre/modules/osfile.jsm")
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
+ "resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
"resource:///modules/RecentWindow.jsm");
XPCOMUtils.defineLazyGetter(this, "DownloadsLogger", () => {
let { ConsoleAPI } = Cu.import("resource://gre/modules/Console.jsm", {});
let consoleOptions = {
@@ -737,42 +737,18 @@ DownloadsDataCtor.prototype = {
if (oldState != newState) {
if (download.succeeded ||
(download.canceled && !download.hasPartialData) ||
download.error) {
// Store the end time that may be displayed by the views.
download.endTime = Date.now();
// This state transition code should actually be located in a Downloads
- // API module (bug 941009). Moreover, the fact that state is stored as
- // annotations should be ideally hidden behind methods of
- // nsIDownloadHistory (bug 830415).
- if (!this._isPrivate) {
- try {
- let downloadMetaData = {
- state: DownloadsCommon.stateOfDownload(download),
- endTime: download.endTime,
- };
- if (download.succeeded) {
- downloadMetaData.fileSize = download.target.size;
- }
- if (download.error && download.error.reputationCheckVerdict) {
- downloadMetaData.reputationCheckVerdict =
- download.error.reputationCheckVerdict;
- }
-
- PlacesUtils.annotations.setPageAnnotation(
- NetUtil.newURI(download.source.url),
- "downloads/metaData",
- JSON.stringify(downloadMetaData), 0,
- PlacesUtils.annotations.EXPIRE_WITH_HISTORY);
- } catch (ex) {
- Cu.reportError(ex);
- }
- }
+ // API module (bug 941009).
+ DownloadHistory.updateMetaData(download);
}
if (download.succeeded ||
(download.error && download.error.becauseBlocked)) {
this._notifyDownloadEvent("finish");
}
}
new file mode 100644
--- /dev/null
+++ b/toolkit/components/jsdownloads/src/DownloadHistory.jsm
@@ -0,0 +1,91 @@
+/* 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/. */
+
+/**
+ * Provides access to downloads from previous sessions on platforms that store
+ * them in a different location than session downloads.
+ *
+ * This module works with objects that are compatible with Download, while using
+ * the Places interfaces internally. Some of the Places objects may also be
+ * exposed to allow the consumers to integrate with history view commands.
+ */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = [
+ "DownloadHistory",
+];
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
+ "resource://gre/modules/PlacesUtils.jsm");
+
+const METADATA_ANNO = "downloads/metaData";
+
+const METADATA_STATE_FINISHED = 1;
+const METADATA_STATE_FAILED = 2;
+const METADATA_STATE_CANCELED = 3;
+const METADATA_STATE_BLOCKED_PARENTAL = 6;
+const METADATA_STATE_DIRTY = 8;
+
+/**
+ * Provides methods to retrieve downloads from previous sessions and store
+ * downloads for future sessions.
+ */
+this.DownloadHistory = {
+ /**
+ * Stores new detailed metadata for the given download in history. This is
+ * normally called after a download finishes, fails, or is canceled.
+ *
+ * Failed or canceled downloads with partial data are not stored as paused,
+ * because the information from the session download is required for resuming.
+ *
+ * @param download
+ * Download object whose metadata should be updated. If the object
+ * represents a private download, the call has no effect.
+ */
+ updateMetaData(download) {
+ if (download.source.isPrivate || !download.stopped) {
+ return;
+ }
+
+ let state = METADATA_STATE_CANCELED;
+ if (download.succeeded) {
+ state = METADATA_STATE_FINISHED;
+ } else if (download.error) {
+ if (download.error.becauseBlockedByParentalControls) {
+ state = METADATA_STATE_BLOCKED_PARENTAL;
+ } else if (download.error.becauseBlockedByReputationCheck) {
+ state = METADATA_STATE_DIRTY;
+ } else {
+ state = METADATA_STATE_FAILED;
+ }
+ }
+
+ let metaData = { state, endTime: download.endTime };
+ if (download.succeeded) {
+ metaData.fileSize = download.target.size;
+ }
+
+ // The verdict may still be present even if the download succeeded.
+ if (download.error && download.error.reputationCheckVerdict) {
+ metaData.reputationCheckVerdict =
+ download.error.reputationCheckVerdict;
+ }
+
+ try {
+ PlacesUtils.annotations.setPageAnnotation(
+ Services.io.newURI(download.source.url),
+ METADATA_ANNO,
+ JSON.stringify(metaData), 0,
+ PlacesUtils.annotations.EXPIRE_WITH_HISTORY);
+ } catch (ex) {
+ Cu.reportError(ex);
+ }
+ },
+};
--- a/toolkit/components/jsdownloads/src/moz.build
+++ b/toolkit/components/jsdownloads/src/moz.build
@@ -17,11 +17,16 @@ EXTRA_JS_MODULES += [
'DownloadCore.jsm',
'DownloadIntegration.jsm',
'DownloadList.jsm',
'Downloads.jsm',
'DownloadStore.jsm',
'DownloadUIHelper.jsm',
]
+if CONFIG['MOZ_PLACES']:
+ EXTRA_JS_MODULES += [
+ 'DownloadHistory.jsm',
+ ]
+
FINAL_LIBRARY = 'xul'
CXXFLAGS += CONFIG['TK_CFLAGS']