p2p: Add HttpPeer to DownloadSource enumeration

This way the Installer.DownloadSourcesUsed metric conveys how often
p2p is used and new metrics Installer.SuccessfulMBsDownloadedFromHttpPeer
and Installer.TotalMBsDownloadedFromHttpPeer gives additional detail.

BUG=chromium:284714
TEST=modify unit tests to cover this case + unit tests pass

Change-Id: Ia4dff090091a282e1a184c2b18f8290749f5fdeb
Reviewed-on: https://chromium-review.googlesource.com/167913
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: David Zeuthen <zeuthen@chromium.org>
Tested-by: David Zeuthen <zeuthen@chromium.org>
diff --git a/payload_state_unittest.cc b/payload_state_unittest.cc
index fc6b4e9..613940e 100644
--- a/payload_state_unittest.cc
+++ b/payload_state_unittest.cc
@@ -42,6 +42,10 @@
   "current-bytes-downloaded-from-HttpServer";
 const char* kTotalBytesDownloadedFromHttp =
   "total-bytes-downloaded-from-HttpServer";
+const char* kCurrentBytesDownloadedFromHttpPeer =
+  "current-bytes-downloaded-from-HttpPeer";
+const char* kTotalBytesDownloadedFromHttpPeer =
+  "total-bytes-downloaded-from-HttpPeer";
 
 static void SetupPayloadStateWith2Urls(string hash,
                                        bool http_enabled,
@@ -117,6 +121,8 @@
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
     .Times(AtLeast(1));
+  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
+    .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
   PayloadState payload_state;
   EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
@@ -165,6 +171,8 @@
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
     .Times(AtLeast(1));
+  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
+    .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
       .Times(AtLeast(1));
   PayloadState payload_state;
@@ -212,6 +220,8 @@
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
     .Times(AtLeast(1));
+  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
+    .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0))
       .Times(AtLeast(1));
 
@@ -387,6 +397,8 @@
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
     .Times(AtLeast(1));
+  EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
+    .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
     .Times(AtLeast(1));
   EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
@@ -803,6 +815,16 @@
   EXPECT_EQ(https_total,
             payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
 
+  // Simulate error (will cause URL switch), set p2p is to be used and
+  // then do 42MB worth of progress
+  payload_state.UpdateFailed(error);
+  payload_state.SetUsingP2PForDownloading(true);
+  int p2p_total = 42 * 1000 * 1000;
+  payload_state.DownloadProgress(p2p_total);
+
+  EXPECT_EQ(p2p_total,
+            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
+
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
     .Times(AnyNumber());
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
@@ -818,8 +840,14 @@
       "Installer.TotalMBsDownloadedFromHttpsServer",
       https_total / kNumBytesInOneMiB, _, _, _));
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
+      "Installer.SuccessfulMBsDownloadedFromHttpPeer",
+      p2p_total / kNumBytesInOneMiB, _, _, _));
+  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
+      "Installer.TotalMBsDownloadedFromHttpPeer",
+      p2p_total / kNumBytesInOneMiB, _, _, _));
+  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
       "Installer.UpdateURLSwitches",
-      2, _, _, _));
+      3, _, _, _));
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
       "Installer.UpdateDurationMinutes",
       _, _, _, _));
@@ -827,9 +855,12 @@
       "Installer.UpdateDurationUptimeMinutes",
       _, _, _, _));
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
-      "Installer.DownloadSourcesUsed", 3, _, _, _));
+      "Installer.DownloadSourcesUsed",
+      (1 << kDownloadSourceHttpsServer) | (1 << kDownloadSourceHttpServer) |
+      (1 << kDownloadSourceHttpPeer),
+      _, _, _));
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
-      "Installer.DownloadOverheadPercentage", 542, _, _, _));
+      "Installer.DownloadOverheadPercentage", 318, _, _, _));
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendEnumToUMA(
       "Installer.PayloadFormat", kPayloadTypeFull, kNumPayloadTypes));
   EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
@@ -849,6 +880,35 @@
   EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
 }
 
+TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
+  OmahaResponse response;
+  PayloadState payload_state;
+  MockSystemState mock_system_state;
+
+  EXPECT_TRUE(payload_state.Initialize(&mock_system_state));
+  SetupPayloadStateWith2Urls("Hash3286", true, &payload_state, &response);
+
+  // Simulate progress in order to mark HTTP as one of the sources used.
+  int num_bytes = 42 * 1000 * 1000;
+  payload_state.DownloadProgress(num_bytes);
+
+  // Check that this was done via HTTP.
+  EXPECT_EQ(num_bytes,
+            payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
+  EXPECT_EQ(num_bytes,
+            payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
+
+  // Check that only HTTP is reported as a download source.
+  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(_, _, _, _, _))
+    .Times(AnyNumber());
+  EXPECT_CALL(*mock_system_state.mock_metrics_lib(), SendToUMA(
+      "Installer.DownloadSourcesUsed",
+      (1 << kDownloadSourceHttpServer),
+      _, _, _));
+
+  payload_state.UpdateSucceeded();
+}
+
 TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
   OmahaResponse response;
   MockSystemState mock_system_state;