Add DownloadSourcesUsed and DownloadOverheadPercentage metrics.

DownloadSourcesUsed: This metric will tell us the various combinations of
the protocols and servers that were used in completing the download for
each successful update attempt.

DownloadOverheadPercentage: This metric will indicate how efficient our
download mechanisms are by calculating the overhead we incurred as a percentage
of the number of bytes that were actually needed to do the update
successfully.

BUG=chromium:225953
TEST=Unit Tests added, chrome://histograms shows new metrics correctly.

Change-Id: Ic1e9547a9a27e1aad53f7e30c70d822820d2c60f
Reviewed-on: https://gerrit.chromium.org/gerrit/48856
Commit-Queue: Jay Srinivasan <jaysri@chromium.org>
Reviewed-by: Jay Srinivasan <jaysri@chromium.org>
Tested-by: Jay Srinivasan <jaysri@chromium.org>
diff --git a/payload_state.cc b/payload_state.cc
index 31c4e42..5ab6028 100644
--- a/payload_state.cc
+++ b/payload_state.cc
@@ -404,14 +404,24 @@
   // Report metrics collected from all known download sources to UMA.
   // The reported data is in Megabytes in order to represent a larger
   // sample range.
+  int download_sources_used = 0;
+  string metric;
+  uint64_t successful_mbs = 0;
+  uint64_t total_mbs = 0;
   for (int i = 0; i < kNumDownloadSources; i++) {
     DownloadSource source = static_cast<DownloadSource>(i);
     const int kMaxMiBs = 10240; // Anything above 10GB goes in the last bucket.
 
-    string metric = "Installer.SuccessfulMBsDownloadedFrom" +
-      utils::ToString(source);
+    metric = "Installer.SuccessfulMBsDownloadedFrom" + utils::ToString(source);
     uint64_t mbs = GetCurrentBytesDownloaded(source) / kNumBytesInOneMiB;
-    LOG(INFO) << "Uploading " << mbs << " (MBs) for metric " <<  metric;
+
+    //  Count this download source as having been used if we downloaded any
+    //  bytes that contributed to the final success of the update.
+    if (mbs)
+      download_sources_used |= (1 << source);
+
+    successful_mbs += mbs;
+    LOG(INFO) << "Uploading " << mbs << " (MBs) for metric " << metric;
     system_state_->metrics_lib()->SendToUMA(metric,
                                             mbs,
                                             0,  // min
@@ -421,7 +431,8 @@
 
     metric = "Installer.TotalMBsDownloadedFrom" + utils::ToString(source);
     mbs = GetTotalBytesDownloaded(source) / kNumBytesInOneMiB;
-    LOG(INFO) << "Uploading " << mbs << " (MBs) for metric " <<  metric;
+    total_mbs += mbs;
+    LOG(INFO) << "Uploading " << mbs << " (MBs) for metric " << metric;
     system_state_->metrics_lib()->SendToUMA(metric,
                                             mbs,
                                             0,  // min
@@ -430,6 +441,27 @@
 
     SetTotalBytesDownloaded(source, 0, true);
   }
+
+  metric = "Installer.DownloadSourcesUsed";
+  LOG(INFO) << "Uploading 0x" << std::hex << download_sources_used
+            << " (bit flags) for metric " << metric;
+  int num_buckets = std::min(1 << kNumDownloadSources, kNumDefaultUmaBuckets);
+  system_state_->metrics_lib()->SendToUMA(metric,
+                                          download_sources_used,
+                                          0,  // min
+                                          1 << kNumDownloadSources,
+                                          num_buckets);
+
+  if (successful_mbs) {
+    metric = "Installer.DownloadOverheadPercentage";
+    int percent_overhead = (total_mbs - successful_mbs) * 100 / successful_mbs;
+    LOG(INFO) << "Uploading " << percent_overhead << "% for metric " << metric;
+    system_state_->metrics_lib()->SendToUMA(metric,
+                                            percent_overhead,
+                                            0,    // min: 0% overhead
+                                            1000, // max: 1000% overhead
+                                            kNumDefaultUmaBuckets);
+  }
 }
 
 void PayloadState::ReportUpdateUrlSwitchesMetric() {