Bug 830415 - Part 2 - Move the front-end code that stores download metadata in history to the DownloadHistory module. r=mak
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Wed, 26 Jul 2017 16:12:57 +0100
changeset 420037 b1826fe01838c61584a50af4d2104eca1fc1b724
parent 420036 58dd26b26962b48ab5e1b79a05e35c864ccd52a8
child 420038 6eea5fcd952669d07f9154e64ab3887ded8d8af8
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs830415, 1381411
milestone56.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
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
browser/components/downloads/DownloadsCommon.jsm
toolkit/components/jsdownloads/src/DownloadHistory.jsm
toolkit/components/jsdownloads/src/moz.build
--- 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']