Download source enum for download better metrics.

This CL introduces a new enum that track the download source.

Currently it lives in content/public/browser, and passed in from
content::DownloadUrlParameters. In components/download, there is a one
to one mapping enum for usage in download in progress db, which can not
depend on content/public.

This enum is supposed to used in UMA as suffix for several key metrics
and UKM as Components, and saved in the new in progress level db.

Bug: 786482
Change-Id: I19a2f959eb9e7b0787087cad6c9519acbde13281
Reviewed-on: https://chromium-review.googlesource.com/777548
Commit-Queue: Xing Liu <[email protected]>
Reviewed-by: David Trainor <[email protected]>
Reviewed-by: Jochen Eisinger <[email protected]>
Reviewed-by: Min Qin <[email protected]>
Cr-Commit-Position: refs/heads/master@{#519928}
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 837b3c9..f8830e1 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -980,8 +980,9 @@
   download::InProgressCache* in_progress_cache =
       GetBrowserContext()->GetDownloadManagerDelegate()->GetInProgressCache();
   if (in_progress_cache) {
-    in_progress_cache->AddOrReplaceEntry(download::DownloadEntry(
-        params.get()->guid(), params.get()->request_origin()));
+    in_progress_cache->AddOrReplaceEntry(
+        download::DownloadEntry(params->guid(), params->request_origin(),
+                                ToDownloadSource(params->download_source())));
   }
 
   if (base::FeatureList::IsEnabled(features::kNetworkService)) {
diff --git a/content/browser/download/download_stats.cc b/content/browser/download/download_stats.cc
index dbb9a18..24d6481 100644
--- a/content/browser/download/download_stats.cc
+++ b/content/browser/download/download_stats.cc
@@ -273,7 +273,7 @@
       "Download.Counts", type, DOWNLOAD_COUNT_TYPES_LAST_ENTRY);
 }
 
-void RecordDownloadSource(DownloadSource source) {
+void RecordDownloadSource(DownloadTriggerSource source) {
   UMA_HISTOGRAM_ENUMERATION(
       "Download.Sources", source, DOWNLOAD_SOURCE_LAST_ENTRY);
 }
diff --git a/content/browser/download/download_stats.h b/content/browser/download/download_stats.h
index 3aeb473..ca82af1 100644
--- a/content/browser/download/download_stats.h
+++ b/content/browser/download/download_stats.h
@@ -123,7 +123,8 @@
   DOWNLOAD_COUNT_TYPES_LAST_ENTRY
 };
 
-enum DownloadSource {
+// TODO(xingliu): Deprecate this enum.
+enum DownloadTriggerSource {
   // The download was initiated when the SavePackage system rejected
   // a Save Page As ... by returning false from
   // SavePackage::IsSaveableContents().
@@ -205,7 +206,7 @@
 void RecordDownloadCount(DownloadCountTypes type);
 
 // Record initiation of a download from a specific source.
-void RecordDownloadSource(DownloadSource source);
+void RecordDownloadSource(DownloadTriggerSource source);
 
 // Record COMPLETED_COUNT and how long the download took.
 void RecordDownloadCompleted(const base::TimeTicks& start,
diff --git a/content/browser/download/download_utils.cc b/content/browser/download/download_utils.cc
index 27bec64..5f198aa0 100644
--- a/content/browser/download/download_utils.cc
+++ b/content/browser/download/download_utils.cc
@@ -405,4 +405,40 @@
        headers->response_code() == net::HTTP_PARTIAL_CONTENT);
 }
 
+download::DownloadSource ToDownloadSource(
+    content::DownloadSource download_source) {
+  switch (download_source) {
+    case DownloadSource::UNKNOWN:
+      return download::DownloadSource::UNKNOWN;
+    case DownloadSource::NAVIGATION:
+      return download::DownloadSource::NAVIGATION;
+    case DownloadSource::DRAG_AND_DROP:
+      return download::DownloadSource::DRAG_AND_DROP;
+    case DownloadSource::MANUAL_RESUMPTION:
+      return download::DownloadSource::MANUAL_RESUMPTION;
+    case DownloadSource::AUTO_RESUMPTION:
+      return download::DownloadSource::AUTO_RESUMPTION;
+    case DownloadSource::FROM_RENDERER:
+      return download::DownloadSource::FROM_RENDERER;
+    case DownloadSource::EXTENSION_API:
+      return download::DownloadSource::EXTENSION_API;
+    case DownloadSource::EXTENSION_INSTALLER:
+      return download::DownloadSource::EXTENSION_INSTALLER;
+    case DownloadSource::PLUGIN:
+      return download::DownloadSource::PLUGIN;
+    case DownloadSource::PLUGIN_INSTALLER:
+      return download::DownloadSource::PLUGIN_INSTALLER;
+    case DownloadSource::INTERNAL_API:
+      return download::DownloadSource::INTERNAL_API;
+    case DownloadSource::SAVE_PACKAGE:
+      return download::DownloadSource::SAVE_PACKAGE;
+    case DownloadSource::OFFLINE_PAGE:
+      return download::DownloadSource::OFFLINE_PAGE;
+    case DownloadSource::COUNT:
+      break;
+  }
+  NOTREACHED();
+  return download::DownloadSource::UNKNOWN;
+}
+
 }  // namespace content
diff --git a/content/browser/download/download_utils.h b/content/browser/download/download_utils.h
index b1cafe2..dd7856c 100644
--- a/content/browser/download/download_utils.h
+++ b/content/browser/download/download_utils.h
@@ -5,7 +5,9 @@
 #ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
 #define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
 
+#include "components/download/downloader/in_progress/download_source.h"
 #include "content/public/browser/download_interrupt_reasons.h"
+#include "content/public/browser/download_source.h"
 #include "net/base/net_errors.h"
 #include "net/cert/cert_status_flags.h"
 #include "net/http/http_response_headers.h"
@@ -48,6 +50,10 @@
     const net::HttpResponseHeaders* headers,
     DownloadCreateInfo* create_info);
 
+// Converts content::DownloadSource to download::DownloadSource.
+CONTENT_EXPORT download::DownloadSource ToDownloadSource(
+    content::DownloadSource download_source);
+
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_UTILS_H_
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 46106f4..ab5fdf3 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -118,6 +118,7 @@
     "download_request_utils.h",
     "download_save_info.cc",
     "download_save_info.h",
+    "download_source.h",
     "download_url_parameters.cc",
     "download_url_parameters.h",
     "favicon_status.cc",
diff --git a/content/public/browser/download_source.h b/content/public/browser/download_source.h
new file mode 100644
index 0000000..040fd01
--- /dev/null
+++ b/content/public/browser/download_source.h
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DOWNLOAD_SOURCE_H_
+#define CONTENT_PUBLIC_BROWSER_DOWNLOAD_SOURCE_H_
+
+namespace content {
+
+// The source of download.
+// Used in UMA metrics and persisted to disk.
+// Entries in this enum can only be appended instead of being deleted or reused.
+// Any changes here also needs to apply to enums.xml.
+enum class DownloadSource {
+  // The source is unknown.
+  UNKNOWN = 0,
+
+  // Download is triggered from navigation request.
+  NAVIGATION = 1,
+
+  // Drag and drop.
+  DRAG_AND_DROP = 2,
+
+  // User manually resume the download.
+  MANUAL_RESUMPTION = 3,
+
+  // Auto resumption in download system.
+  AUTO_RESUMPTION = 4,
+
+  // Renderer initiated download, mostly from Javascript or HTML <a> tag.
+  FROM_RENDERER = 5,
+
+  // Extension download API.
+  EXTENSION_API = 6,
+
+  // Extension web store installer.
+  EXTENSION_INSTALLER = 7,
+
+  // Plugin triggered download.
+  PLUGIN = 8,
+
+  // Plugin installer download.
+  PLUGIN_INSTALLER = 9,
+
+  // Download service API background download.
+  INTERNAL_API = 10,
+
+  // Save package download.
+  SAVE_PACKAGE = 11,
+
+  // Offline page download.
+  OFFLINE_PAGE = 12,
+
+  COUNT = 13
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_DOWNLOAD_SOURCE_H_
diff --git a/content/public/browser/download_url_parameters.cc b/content/public/browser/download_url_parameters.cc
index 39665ac..3151376 100644
--- a/content/public/browser/download_url_parameters.cc
+++ b/content/public/browser/download_url_parameters.cc
@@ -47,7 +47,8 @@
       do_not_prompt_for_login_(false),
       fetch_error_body_(false),
       transient_(false),
-      traffic_annotation_(traffic_annotation) {}
+      traffic_annotation_(traffic_annotation),
+      download_source_(DownloadSource::UNKNOWN) {}
 
 DownloadUrlParameters::~DownloadUrlParameters() {
 }
diff --git a/content/public/browser/download_url_parameters.h b/content/public/browser/download_url_parameters.h
index e74b084..f1584852 100644
--- a/content/public/browser/download_url_parameters.h
+++ b/content/public/browser/download_url_parameters.h
@@ -18,6 +18,7 @@
 #include "base/optional.h"
 #include "content/public/browser/download_interrupt_reasons.h"
 #include "content/public/browser/download_save_info.h"
+#include "content/public/browser/download_source.h"
 #include "content/public/common/referrer.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -244,6 +245,11 @@
     request_origin_ = origin;
   }
 
+  // Sets the download source, which will be used in metrics recording.
+  void set_download_source(DownloadSource download_source) {
+    download_source_ = download_source;
+  }
+
   const OnStartedCallback& callback() const { return callback_; }
   bool content_initiated() const { return content_initiated_; }
   const std::string& last_modified() const { return last_modified_; }
@@ -301,6 +307,8 @@
     return traffic_annotation_;
   }
 
+  DownloadSource download_source() const { return download_source_; }
+
  private:
   OnStartedCallback callback_;
   bool content_initiated_;
@@ -328,6 +336,7 @@
   std::unique_ptr<storage::BlobDataHandle> blob_data_handle_;
   const net::NetworkTrafficAnnotationTag traffic_annotation_;
   std::string request_origin_;
+  DownloadSource download_source_;
 
   DISALLOW_COPY_AND_ASSIGN(DownloadUrlParameters);
 };