Tracking received data amounts on a daily basis

Maintain a window of the last 60 days of the amount of HTTP
data received.

BUG=174531


Review URL: https://chromiumcodereview.appspot.com/12664006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@189127 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 1630a52..5dee970 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/net/chrome_network_delegate.h"
 
+#include <stdlib.h>
+
 #include <vector>
 
 #include "base/base_paths.h"
@@ -28,6 +30,7 @@
 #include "chrome/browser/net/connect_interceptor.h"
 #include "chrome/browser/net/load_time_stats.h"
 #include "chrome/browser/performance_monitor/performance_monitor.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/task_manager/task_manager.h"
 #include "chrome/common/pref_names.h"
@@ -209,6 +212,25 @@
   }
 }
 
+#if defined(OS_ANDROID)
+// Increments an int64, stored as a string, in a ListPref at the specified
+// index.  The value must already exist and be a string representation of a
+// number.
+void AddInt64ToListPref(size_t index, int64 length,
+                        ListPrefUpdate& list_update) {
+  int64 value = 0;
+  std::string old_string_value;
+  bool rv = list_update->GetString(index, &old_string_value);
+  DCHECK(rv);
+  if (rv) {
+    rv = base::StringToInt64(old_string_value, &value);
+    DCHECK(rv);
+  }
+  value += length;
+  list_update->Set(index, Value::CreateStringValue(base::Int64ToString(value)));
+}
+#endif  // defined(OS_ANDROID)
+
 void UpdateContentLengthPrefs(int received_content_length,
                               int original_content_length) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -229,6 +251,72 @@
   total_original += original_content_length;
   prefs->SetInt64(prefs::kHttpReceivedContentLength, total_received);
   prefs->SetInt64(prefs::kHttpOriginalContentLength, total_original);
+
+#if defined(OS_ANDROID)
+  base::Time now = base::Time::Now().LocalMidnight();
+  const size_t kNumDaysInHistory = 60;
+
+  // Each day, we calculate the total number of bytes received and the total
+  // size of all corresponding resources before any data-reducing recompression
+  // is applied. These values are used to compute the data savings realized
+  // by applying our compression techniques. Totals for the last
+  // |kNumDaysInHistory| days are maintained.
+  ListPrefUpdate original_update(prefs, prefs::kDailyHttpOriginalContentLength);
+  ListPrefUpdate received_update(prefs, prefs::kDailyHttpReceivedContentLength);
+
+  // Determine how many days it has been since the last update.
+  int64 then_internal = prefs->GetInt64(
+      prefs::kDailyHttpContentLengthLastUpdateDate);
+  base::Time then = base::Time::FromInternalValue(then_internal);
+  int days_since_last_update = (now - then).InDays();
+
+  if (days_since_last_update) {
+    // Record the last update time.
+    prefs->SetInt64(prefs::kDailyHttpContentLengthLastUpdateDate,
+                    now.ToInternalValue());
+
+    if (days_since_last_update == -1) {
+      // The system may go backwards in time by up to a day for legitimate
+      // reasons, such as with changes to the time zone. In such cases the
+      // history is likely still valid. Shift backwards one day and retain all
+      // values.
+      original_update->Remove(kNumDaysInHistory - 1, NULL);
+      received_update->Remove(kNumDaysInHistory - 1, NULL);
+      original_update->Insert(0, new StringValue(base::Int64ToString(0)));
+      received_update->Insert(0, new StringValue(base::Int64ToString(0)));
+      days_since_last_update = 0;
+
+    } else if (days_since_last_update < -1) {
+      // Erase all entries if the system went backwards in time by more than
+      // a day.
+      original_update->Clear();
+      days_since_last_update = kNumDaysInHistory;
+    }
+
+    // Add entries for days since last update.
+    for (int i = 0;
+         i < days_since_last_update && i < static_cast<int>(kNumDaysInHistory);
+         ++i) {
+      original_update->AppendString(base::Int64ToString(0));
+      received_update->AppendString(base::Int64ToString(0));
+    }
+
+    // Maintain the invariant that there should never be more than
+    // |kNumDaysInHistory| days in the histories.
+    while (original_update->GetSize() > kNumDaysInHistory)
+      original_update->Remove(0, NULL);
+    while (received_update->GetSize() > kNumDaysInHistory)
+      received_update->Remove(0, NULL);
+  }
+  DCHECK_EQ(kNumDaysInHistory, original_update->GetSize());
+  DCHECK_EQ(kNumDaysInHistory, received_update->GetSize());
+
+  // Update the counts for the current day.
+  AddInt64ToListPref(kNumDaysInHistory - 1,
+                     original_content_length, original_update);
+  AddInt64ToListPref(kNumDaysInHistory - 1,
+                     received_content_length, received_update);
+#endif
 }
 
 void StoreAccumulatedContentLength(int received_content_length,