[go: up one dir, main page]

DataReductionProxyStatisticsPrefs should support WeakPtr

The DRPStatisticsPrefs object is referenced via a raw pointer in
DRPNetworkDelegate and DRPSettings. It should instead be referenced
via WeakPtr.

BUG=453155,455559,444939

Committed: https://crrev.com/149bd770d674e8125f81cd649a8deece3a851682
Cr-Commit-Position: refs/heads/master@{#315419}

Review URL: https://codereview.chromium.org/888713002

Cr-Commit-Position: refs/heads/master@{#315621}
(cherry picked from commit 85594ccf495b97ccd4642dd5f5ab98e31d1d2003)

Review URL: https://codereview.chromium.org/918363002

Cr-Commit-Position: refs/branch-heads/2272@{#299}
Cr-Branched-From: 827a380cfdb31aa54c8d56e63ce2c3fd8c3ba4d4-refs/heads/master@{#310958}
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
index 1fea722..27235b5 100644
--- a/android_webview/browser/aw_browser_context.cc
+++ b/android_webview/browser/aw_browser_context.cc
@@ -123,8 +123,6 @@
     return;
 
   context->CreateDataReductionProxyStatisticsIfNecessary();
-  proxy_settings->SetDataReductionProxyStatisticsPrefs(
-      context->data_reduction_proxy_statistics_.get());
   proxy_settings->SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
 }
 
@@ -264,6 +262,7 @@
   if (data_reduction_proxy_settings_.get()) {
     data_reduction_proxy_settings_->InitDataReductionProxySettings(
         user_pref_service_.get(),
+        scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>(),
         GetRequestContext(),
         GetAwURLRequestContext()->GetNetLog(),
         GetDataReductionProxyEventStore());
@@ -360,17 +359,17 @@
 
 void AwBrowserContext::CreateDataReductionProxyStatisticsIfNecessary() {
   DCHECK(user_pref_service_.get());
-
-  if (!data_reduction_proxy_statistics_.get()) {
-    // We don't care about commit_delay for now. It is just a dummy value.
-    base::TimeDelta commit_delay = base::TimeDelta::FromMinutes(60);
-    data_reduction_proxy_statistics_ =
-        scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>(
-            new data_reduction_proxy::DataReductionProxyStatisticsPrefs(
-                user_pref_service_.get(),
-                base::MessageLoopProxy::current(),
-                commit_delay));
-  }
+  DCHECK(GetDataReductionProxySettings());
+  if (data_reduction_proxy_statistics_)
+    return;
+  // We don't care about commit_delay for now. It is just a dummy value.
+  base::TimeDelta commit_delay = base::TimeDelta::FromMinutes(60);
+  GetDataReductionProxySettings()->EnableCompressionStatisticsLogging(
+      user_pref_service_.get(),
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+      commit_delay);
+  data_reduction_proxy_statistics_ =
+      GetDataReductionProxySettings()->statistics_prefs();
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
index a821acf7..696a710d 100644
--- a/android_webview/browser/aw_browser_context.h
+++ b/android_webview/browser/aw_browser_context.h
@@ -14,6 +14,7 @@
 #include "base/files/file_path.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "components/visitedlink/browser/visitedlink_delegate.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
@@ -153,7 +154,7 @@
 
   scoped_ptr<data_reduction_proxy::DataReductionProxyConfigurator>
       data_reduction_proxy_configurator_;
-  scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+  base::WeakPtr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
       data_reduction_proxy_statistics_;
   scoped_ptr<data_reduction_proxy::DataReductionProxySettings>
       data_reduction_proxy_settings_;
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc
index 6521672..842e1d6 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.cc
@@ -16,6 +16,7 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "net/url_request/url_request_context_getter.h"
 
@@ -68,12 +69,15 @@
     data_reduction_proxy::DataReductionProxyConfigurator* configurator,
     PrefService* profile_prefs,
     PrefService* local_state_prefs,
+    scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+        statistics_prefs,
     net::URLRequestContextGetter* request_context,
     net::NetLog* net_log,
     data_reduction_proxy::DataReductionProxyEventStore* event_store) {
   SetProxyConfigurator(configurator);
   DataReductionProxySettings::InitDataReductionProxySettings(
       profile_prefs,
+      statistics_prefs.Pass(),
       request_context,
       net_log,
       event_store);
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h
index 92130cb..9d1ee8e 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_CHROME_SETTINGS_H_
 
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -18,6 +19,7 @@
 class DataReductionProxyConfigurator;
 class DataReductionProxyEventStore;
 class DataReductionProxyParams;
+class DataReductionProxyStatisticsPrefs;
 }
 
 namespace net {
@@ -42,11 +44,14 @@
   ~DataReductionProxyChromeSettings() override;
 
   // Initialize the settings object with the given configurator, prefs services,
-  // and request context.
+  // and request context. Settings takes ownership of statistics prefs from
+  // |io_data|.
   void InitDataReductionProxySettings(
       data_reduction_proxy::DataReductionProxyConfigurator* configurator,
       PrefService* profile_prefs,
       PrefService* local_state_prefs,
+      scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+          statistics_prefs,
       net::URLRequestContextGetter* request_context,
       net::NetLog* net_log,
       data_reduction_proxy::DataReductionProxyEventStore* event_store);
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
index d60ba1d4..591b781 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc
@@ -9,12 +9,17 @@
 #include "base/android/scoped_java_ref.h"
 #include "base/base64.h"
 #include "base/command_line.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/prefs/pref_service.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/time/time.h"
 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h"
 #include "chrome/browser/prefs/proxy_prefs.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -76,7 +81,13 @@
   EXPECT_CALL(*settings, GetURLFetcherForAvailabilityCheck()).Times(0);
   EXPECT_CALL(*settings, LogProxyState(_, _, _)).Times(0);
   settings_.reset(settings);
-  settings_->SetDataReductionProxyStatisticsPrefs(statistics_prefs_.get());
+  settings_->SetDataReductionProxyStatisticsPrefs(
+      scoped_ptr<DataReductionProxyStatisticsPrefs>(
+          new DataReductionProxyStatisticsPrefs(
+              &pref_service_,
+              scoped_refptr<base::TestSimpleTaskRunner>(
+                  new base::TestSimpleTaskRunner()),
+              base::TimeDelta())));
 }
 
 template <class C>
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 259c15e..6ae5809d 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -699,8 +699,6 @@
               prefs_.get(),
               base::MessageLoopProxy::current(),
               commit_delay));
-  data_reduction_proxy_chrome_settings->SetDataReductionProxyStatisticsPrefs(
-      data_reduction_proxy_statistics_prefs.get());
 
   // Make sure we initialize the ProfileIOData after everything else has been
   // initialized that we might be reading from the IO thread.
@@ -713,12 +711,13 @@
                 data_reduction_proxy_unavailable,
                 configurator.Pass(),
                 data_reduction_proxy_params.Pass(),
-                data_reduction_proxy_statistics_prefs.Pass(),
+                data_reduction_proxy_statistics_prefs->GetWeakPtr(),
                 event_store.Pass());
   data_reduction_proxy_chrome_settings->InitDataReductionProxySettings(
       data_reduction_proxy_configurator,
       prefs_.get(),
       g_browser_process->local_state(),
+      data_reduction_proxy_statistics_prefs.Pass(),
       GetRequestContext(),
       net_log,
       data_reduction_proxy_event_store);
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 7c90a49..80773eb 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -143,7 +143,7 @@
         data_reduction_proxy_configurator,
     scoped_ptr<data_reduction_proxy::DataReductionProxyParams>
         data_reduction_proxy_params,
-    scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+    base::WeakPtr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
         data_reduction_proxy_statistics_prefs,
     scoped_ptr<data_reduction_proxy::DataReductionProxyEventStore>
         data_reduction_proxy_event_store) {
@@ -185,7 +185,7 @@
       data_reduction_proxy_configurator.Pass());
   io_data_->set_data_reduction_proxy_params(data_reduction_proxy_params.Pass());
   io_data_->set_data_reduction_proxy_statistics_prefs(
-      data_reduction_proxy_statistics_prefs.Pass());
+      data_reduction_proxy_statistics_prefs);
   io_data_->set_data_reduction_proxy_event_store(
       data_reduction_proxy_event_store.Pass());
 }
diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h
index 8ea0f1a8..e6e3b19 100644
--- a/chrome/browser/profiles/profile_impl_io_data.h
+++ b/chrome/browser/profiles/profile_impl_io_data.h
@@ -74,7 +74,7 @@
             data_reduction_proxy_configurator,
         scoped_ptr<data_reduction_proxy::DataReductionProxyParams>
             data_reduction_proxy_params,
-        scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+        base::WeakPtr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
             data_reduction_proxy_statistics_prefs,
         scoped_ptr<data_reduction_proxy::DataReductionProxyEventStore>
             data_reduction_proxy_event_store);
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 8c821a9..2bf465f 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -1253,8 +1253,6 @@
   quick_check_enabled_.Destroy();
   if (media_device_id_salt_.get())
     media_device_id_salt_->ShutdownOnUIThread();
-  if (data_reduction_proxy_statistics_prefs_.get())
-    data_reduction_proxy_statistics_prefs_->ShutdownOnUIThread();
   session_startup_pref_.Destroy();
 #if defined(ENABLE_CONFIGURATION_POLICY)
   if (url_blacklist_manager_)
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index 966e86b..c3b43b5 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -384,15 +384,15 @@
   }
 
   void set_data_reduction_proxy_statistics_prefs(
-      scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+      base::WeakPtr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
           data_reduction_proxy_statistics_prefs) {
     data_reduction_proxy_statistics_prefs_ =
-        data_reduction_proxy_statistics_prefs.Pass();
+        data_reduction_proxy_statistics_prefs;
   }
 
-  data_reduction_proxy::DataReductionProxyStatisticsPrefs*
+  base::WeakPtr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
       data_reduction_proxy_statistics_prefs() const {
-    return data_reduction_proxy_statistics_prefs_.get();
+    return data_reduction_proxy_statistics_prefs_;
   }
 
   void set_data_reduction_proxy_usage_stats(
@@ -653,7 +653,7 @@
       data_reduction_proxy_params_;
   mutable scoped_ptr<data_reduction_proxy::DataReductionProxyUsageStats>
       data_reduction_proxy_usage_stats_;
-  mutable scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
+  mutable base::WeakPtr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>
       data_reduction_proxy_statistics_prefs_;
   mutable base::Callback<void(bool)> data_reduction_proxy_unavailable_callback_;
   mutable scoped_ptr<data_reduction_proxy::DataReductionProxyConfigurator>
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc
index c712a15..e14c0aa 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc
@@ -466,32 +466,4 @@
   }
 }
 
-void UpdateContentLengthPrefs(int received_content_length,
-                              int original_content_length,
-                              bool data_reduction_proxy_enabled,
-                              DataReductionProxyRequestType request_type,
-                              DataReductionProxyStatisticsPrefs* prefs) {
-  DCHECK(prefs);
-  int64 total_received = prefs->GetInt64(
-      data_reduction_proxy::prefs::kHttpReceivedContentLength);
-  int64 total_original = prefs->GetInt64(
-      data_reduction_proxy::prefs::kHttpOriginalContentLength);
-  total_received += received_content_length;
-  total_original += original_content_length;
-  prefs->SetInt64(
-      data_reduction_proxy::prefs::kHttpReceivedContentLength,
-      total_received);
-  prefs->SetInt64(
-      data_reduction_proxy::prefs::kHttpOriginalContentLength,
-      total_original);
-
-  UpdateContentLengthPrefsForDataReductionProxy(
-      received_content_length,
-      original_content_length,
-      data_reduction_proxy_enabled,
-      request_type,
-      base::Time::Now(),
-      prefs);
-}
-
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h
index 73c57526..a14a4a75 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h
@@ -55,14 +55,6 @@
     base::Time now,
     DataReductionProxyStatisticsPrefs* prefs);
 
-// Records daily data savings statistics to prefs and reports data savings UMA.
-void UpdateContentLengthPrefs(
-    int received_content_length,
-    int original_content_length,
-    bool data_reduction_proxy_enabled,
-    DataReductionProxyRequestType request_type,
-    DataReductionProxyStatisticsPrefs* prefs);
-
 }  // namespace data_reduction_proxy
 
 #endif  // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_METRICS_H_
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
index 64b0ed1..4584d6c6 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
@@ -91,42 +91,6 @@
   scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs_;
 };
 
-TEST_F(ChromeNetworkDataSavingMetricsTest, TotalLengths) {
-  const int64 kOriginalLength = 200;
-  const int64 kReceivedLength = 100;
-
-  UpdateContentLengthPrefs(
-      kReceivedLength, kOriginalLength,
-      pref_service_.GetBoolean(
-          data_reduction_proxy::prefs::kDataReductionProxyEnabled),
-      UNKNOWN_TYPE, statistics_prefs_.get());
-
-  EXPECT_EQ(kReceivedLength,
-            statistics_prefs_->GetInt64(
-                data_reduction_proxy::prefs::kHttpReceivedContentLength));
-  EXPECT_FALSE(pref_service_.GetBoolean(
-      data_reduction_proxy::prefs::kDataReductionProxyEnabled));
-  EXPECT_EQ(kOriginalLength,
-            statistics_prefs_->GetInt64(
-                data_reduction_proxy::prefs::kHttpOriginalContentLength));
-
-  // Record the same numbers again, and total lengths should be doubled.
-  UpdateContentLengthPrefs(
-      kReceivedLength, kOriginalLength,
-      pref_service_.GetBoolean(
-          data_reduction_proxy::prefs::kDataReductionProxyEnabled),
-      UNKNOWN_TYPE, statistics_prefs_.get());
-
-  EXPECT_EQ(kReceivedLength * 2,
-            statistics_prefs_->GetInt64(
-                data_reduction_proxy::prefs::kHttpReceivedContentLength));
-  EXPECT_FALSE(pref_service_.GetBoolean(
-      data_reduction_proxy::prefs::kDataReductionProxyEnabled));
-  EXPECT_EQ(kOriginalLength * 2,
-            statistics_prefs_->GetInt64(
-                data_reduction_proxy::prefs::kHttpOriginalContentLength));
-}
-
 // The initial last update time used in test. There is no leap second a few
 // days around this time used in the test.
 // Note: No time zone is specified. Local time will be assumed by
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
index 703b22c41..3265efb1 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -5,6 +5,7 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h"
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
 #include "base/single_thread_task_runner.h"
@@ -83,7 +84,6 @@
       data_reduction_proxy_params_(params),
       data_reduction_proxy_usage_stats_(NULL),
       data_reduction_proxy_auth_request_handler_(handler),
-      data_reduction_proxy_statistics_prefs_(NULL),
       proxy_config_getter_(getter) {
   DCHECK(data_reduction_proxy_params_);
   DCHECK(data_reduction_proxy_auth_request_handler_);
@@ -100,10 +100,9 @@
 
 void DataReductionProxyNetworkDelegate::InitStatisticsPrefsAndUMA(
     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
-    DataReductionProxyStatisticsPrefs* statistics_prefs,
+    const base::WeakPtr<DataReductionProxyStatisticsPrefs>& statistics_prefs,
     BooleanPrefMember* data_reduction_proxy_enabled,
     DataReductionProxyUsageStats* usage_stats) {
-  DCHECK(statistics_prefs);
   DCHECK(data_reduction_proxy_enabled);
   DCHECK(usage_stats);
   ui_task_runner_ = ui_task_runner;
@@ -241,21 +240,49 @@
     DataReductionProxyRequestType request_type) {
   DCHECK_GE(received_content_length, 0);
   DCHECK_GE(original_content_length, 0);
-  if (data_reduction_proxy_enabled_ &&
-      data_reduction_proxy_statistics_prefs_) {
+  if (data_reduction_proxy_enabled_) {
     ui_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&UpdateContentLengthPrefs,
+        base::Bind(&DataReductionProxyNetworkDelegate::UpdateContentLengthPrefs,
+                   base::Unretained(this),
                    received_content_length,
                    original_content_length,
                    data_reduction_proxy_enabled_->GetValue(),
-                   request_type,
-                   data_reduction_proxy_statistics_prefs_));
+                   request_type));
   }
   received_content_length_ += received_content_length;
   original_content_length_ += original_content_length;
 }
 
+void DataReductionProxyNetworkDelegate::UpdateContentLengthPrefs(
+    int received_content_length,
+    int original_content_length,
+    bool data_reduction_proxy_enabled,
+    DataReductionProxyRequestType request_type) {
+  if (data_reduction_proxy_statistics_prefs_) {
+    int64 total_received = data_reduction_proxy_statistics_prefs_->GetInt64(
+        data_reduction_proxy::prefs::kHttpReceivedContentLength);
+    int64 total_original = data_reduction_proxy_statistics_prefs_->GetInt64(
+        data_reduction_proxy::prefs::kHttpOriginalContentLength);
+    total_received += received_content_length;
+    total_original += original_content_length;
+    data_reduction_proxy_statistics_prefs_->SetInt64(
+        data_reduction_proxy::prefs::kHttpReceivedContentLength,
+        total_received);
+    data_reduction_proxy_statistics_prefs_->SetInt64(
+        data_reduction_proxy::prefs::kHttpOriginalContentLength,
+        total_original);
+
+    UpdateContentLengthPrefsForDataReductionProxy(
+        received_content_length,
+        original_content_length,
+        data_reduction_proxy_enabled,
+        request_type,
+        base::Time::Now(),
+        data_reduction_proxy_statistics_prefs_.get());
+  }
+}
+
 void OnResolveProxyHandler(const GURL& url,
                            int load_flags,
                            const net::ProxyConfig& data_reduction_proxy_config,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
index 0744b86..179e9a0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
@@ -6,8 +6,10 @@
 #define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_NETWORK_DELEGATE_H_
 
 #include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
 #include "net/base/layered_network_delegate.h"
@@ -85,7 +87,7 @@
   // report UMA.
   void InitStatisticsPrefsAndUMA(
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
-      DataReductionProxyStatisticsPrefs* statistics_prefs,
+      const base::WeakPtr<DataReductionProxyStatisticsPrefs>& statistics_prefs,
       BooleanPrefMember* data_reduction_proxy_enabled,
       DataReductionProxyUsageStats* usage_stats);
 
@@ -100,6 +102,8 @@
   base::Value* SessionNetworkStatsInfoToValue() const;
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyNetworkDelegateTest, TotalLengths);
+
   // Called as the proxy is being resolved for |url|. Allows the delegate to
   // override the proxy resolution decision made by ProxyService. The delegate
   // may override the decision by modifying the ProxyInfo |result|.
@@ -136,6 +140,13 @@
                                int64 original_content_length,
                                DataReductionProxyRequestType request_type);
 
+  // Records daily data savings statistics to prefs and reports data savings
+  // UMA.
+  void UpdateContentLengthPrefs(int received_content_length,
+                                int original_content_length,
+                                bool data_reduction_proxy_enabled,
+                                DataReductionProxyRequestType request_type);
+
   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
 
   // Total size of all content (excluding headers) that has been received
@@ -157,7 +168,8 @@
   DataReductionProxyAuthRequestHandler*
       data_reduction_proxy_auth_request_handler_;
 
-  DataReductionProxyStatisticsPrefs* data_reduction_proxy_statistics_prefs_;
+  base::WeakPtr<DataReductionProxyStatisticsPrefs>
+      data_reduction_proxy_statistics_prefs_;
 
   // TODO(sclittle): Factor this out, see http://crbug.com/447346.
   OnResolveProxyHandler on_resolve_proxy_handler_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
index a385f89..e622673 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -13,11 +13,18 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/histogram_tester.h"
+#include "base/test/test_simple_task_runner.h"
 #include "base/time/time.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_auth_request_handler.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
+#include "net/base/capturing_net_log.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_response_headers.h"
@@ -71,6 +78,30 @@
     EXPECT_TRUE(test_job_factory_.SetProtocolHandler(url::kHttpScheme,
                                                      test_job_interceptor_));
     context_.set_job_factory(&test_job_factory_);
+    event_store_.reset(new DataReductionProxyEventStore(message_loop_proxy()));
+
+    params_.reset(
+        new TestDataReductionProxyParams(
+            DataReductionProxyParams::kAllowed |
+            DataReductionProxyParams::kFallbackAllowed |
+            DataReductionProxyParams::kPromoAllowed,
+            TestDataReductionProxyParams::HAS_EVERYTHING &
+            ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
+            ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN));
+
+    auth_handler_.reset(new DataReductionProxyAuthRequestHandler(
+        kClient, params_.get(), message_loop_proxy()));
+
+    configurator_.reset(new DataReductionProxyConfigurator(
+        message_loop_proxy(), net_log(), event_store()));
+
+    data_reduction_proxy_network_delegate_.reset(
+        new DataReductionProxyNetworkDelegate(
+            scoped_ptr<net::NetworkDelegate>(new TestNetworkDelegate()),
+            params_.get(), auth_handler_.get(),
+            base::Bind(
+                &DataReductionProxyNetworkDelegateTest::GetProxyConfig,
+                base::Unretained(this))));
   }
 
   const net::ProxyConfig& GetProxyConfig() const {
@@ -115,6 +146,20 @@
     return loop_.message_loop_proxy();
   }
 
+  net::NetLog* net_log() {
+    return &net_log_;
+  }
+
+  DataReductionProxyEventStore* event_store() {
+    return event_store_.get();
+  }
+
+  scoped_ptr<TestDataReductionProxyParams> params_;
+  scoped_ptr<DataReductionProxyAuthRequestHandler> auth_handler_;
+  scoped_ptr<DataReductionProxyConfigurator> configurator_;
+  scoped_ptr<DataReductionProxyNetworkDelegate>
+      data_reduction_proxy_network_delegate_;
+
  private:
   base::MessageLoopForIO loop_;
   net::TestURLRequestContext context_;
@@ -125,39 +170,22 @@
 
   net::ProxyConfig config_;
   net::NetworkDelegate* network_delegate_;
+  net::CapturingNetLog net_log_;
+  scoped_ptr<DataReductionProxyEventStore> event_store_;
 };
 
 TEST_F(DataReductionProxyNetworkDelegateTest, AuthenticationTest) {
-  scoped_ptr<TestDataReductionProxyParams> params(
-      new TestDataReductionProxyParams(
-          DataReductionProxyParams::kAllowed |
-          DataReductionProxyParams::kFallbackAllowed |
-          DataReductionProxyParams::kPromoAllowed,
-          TestDataReductionProxyParams::HAS_EVERYTHING &
-          ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-          ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN));
-  // loop_proxy_ is just the current message loop. This means loop_proxy_
-  // is the network thread used by DataReductionProxyAuthRequestHandler.
-  DataReductionProxyAuthRequestHandler auth_handler(
-      kClient, params.get(), message_loop_proxy());
-
-  scoped_ptr<DataReductionProxyNetworkDelegate> network_delegate(
-      new DataReductionProxyNetworkDelegate(
-          scoped_ptr<net::NetworkDelegate>(new TestNetworkDelegate()),
-          params.get(), &auth_handler,
-          DataReductionProxyNetworkDelegate::ProxyConfigGetter()));
-
-  set_network_delegate(network_delegate.get());
+  set_network_delegate(data_reduction_proxy_network_delegate_.get());
   scoped_ptr<net::URLRequest> fake_request(
       FetchURLRequest(GURL("http://www.google.com/"), std::string(), 0));
 
   net::ProxyInfo data_reduction_proxy_info;
   std::string data_reduction_proxy;
-  base::TrimString(params->DefaultOrigin(), "/", &data_reduction_proxy);
+  base::TrimString(params_->DefaultOrigin(), "/", &data_reduction_proxy);
   data_reduction_proxy_info.UseNamedProxy(data_reduction_proxy);
 
   net::HttpRequestHeaders headers;
-  network_delegate->NotifyBeforeSendProxyHeaders(
+  data_reduction_proxy_network_delegate_->NotifyBeforeSendProxyHeaders(
       fake_request.get(), data_reduction_proxy_info, &headers);
 
   EXPECT_TRUE(headers.HasHeader(kChromeProxyHeader));
@@ -188,29 +216,9 @@
   const int64 kResponseContentLength = 100;
   const int64 kOriginalContentLength = 200;
 
-  scoped_ptr<TestDataReductionProxyParams> params(
-      new TestDataReductionProxyParams(
-          DataReductionProxyParams::kAllowed |
-          DataReductionProxyParams::kFallbackAllowed |
-          DataReductionProxyParams::kPromoAllowed,
-          TestDataReductionProxyParams::HAS_EVERYTHING &
-          ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-          ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN));
-  // loop_proxy_ is just the current message loop. This means loop_proxy_
-  // is the network thread used by DataReductionProxyAuthRequestHandler.
-  DataReductionProxyAuthRequestHandler auth_handler(
-      kClient, params.get(), message_loop_proxy());
-
   base::HistogramTester histogram_tester;
-  scoped_ptr<DataReductionProxyNetworkDelegate> network_delegate(
-      new DataReductionProxyNetworkDelegate(
-          scoped_ptr<net::NetworkDelegate>(
-              new TestNetworkDelegate()), params.get(), &auth_handler,
-              base::Bind(
-                  &DataReductionProxyNetworkDelegateTest::GetProxyConfig,
-                  base::Unretained(this))));
 
-  set_network_delegate(network_delegate.get());
+  set_network_delegate(data_reduction_proxy_network_delegate_.get());
 
   std::string raw_headers =
       "HTTP/1.1 200 OK\n"
@@ -254,10 +262,213 @@
                                       kResponseContentLength, 1);
 }
 
+class BadEntropyProvider : public base::FieldTrial::EntropyProvider {
+ public:
+  ~BadEntropyProvider() override {}
+
+  double GetEntropyForTrial(const std::string& trial_name,
+                            uint32 randomization_seed) const override {
+    return 0.5;
+  }
+};
+
+TEST_F(DataReductionProxyNetworkDelegateTest, OnResolveProxyHandler) {
+  int load_flags = net::LOAD_NORMAL;
+  GURL url("http://www.google.com/");
+
+  // Data reduction proxy info
+  net::ProxyInfo data_reduction_proxy_info;
+  std::string data_reduction_proxy;
+  base::TrimString(params_->DefaultOrigin(), "/", &data_reduction_proxy);
+  data_reduction_proxy_info.UsePacString(
+      "PROXY " +
+      net::HostPortPair::FromURL(GURL(params_->DefaultOrigin())).ToString() +
+      "; DIRECT");
+  EXPECT_FALSE(data_reduction_proxy_info.is_empty());
+
+  // Data reduction proxy config
+  net::ProxyConfig data_reduction_proxy_config;
+  data_reduction_proxy_config.proxy_rules().ParseFromString(
+      "http=" + data_reduction_proxy + ",direct://;");
+  data_reduction_proxy_config.set_id(1);
+
+  // Other proxy info
+  net::ProxyInfo other_proxy_info;
+  other_proxy_info.UseNamedProxy("proxy.com");
+  EXPECT_FALSE(other_proxy_info.is_empty());
+
+  // Direct
+  net::ProxyInfo direct_proxy_info;
+  direct_proxy_info.UseDirect();
+  EXPECT_TRUE(direct_proxy_info.is_direct());
+
+  // Empty retry info map
+  net::ProxyRetryInfoMap empty_proxy_retry_info;
+
+  // Retry info map with the data reduction proxy;
+  net::ProxyRetryInfoMap data_reduction_proxy_retry_info;
+  net::ProxyRetryInfo retry_info;
+  retry_info.current_delay = base::TimeDelta::FromSeconds(1000);
+  retry_info.bad_until = base::TimeTicks().Now() + retry_info.current_delay;
+  retry_info.try_while_bad = false;
+  data_reduction_proxy_retry_info[
+     data_reduction_proxy_info.proxy_server().ToURI()] = retry_info;
+
+  net::ProxyInfo result;
+  // Another proxy is used. It should be used afterwards.
+  result.Use(other_proxy_info);
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(), &result);
+  EXPECT_EQ(other_proxy_info.proxy_server(), result.proxy_server());
+
+  // A direct connection is used. The data reduction proxy should be used
+  // afterwards.
+  // Another proxy is used. It should be used afterwards.
+  result.Use(direct_proxy_info);
+  net::ProxyConfig::ID prev_id = result.config_id();
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(), &result);
+  EXPECT_EQ(data_reduction_proxy_info.proxy_server(), result.proxy_server());
+  // Only the proxy list should be updated, not he proxy info.
+  EXPECT_EQ(result.config_id(), prev_id);
+
+  // A direct connection is used, but the data reduction proxy is on the retry
+  // list. A direct connection should be used afterwards.
+  result.Use(direct_proxy_info);
+  prev_id = result.config_id();
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        data_reduction_proxy_retry_info,
+                        params_.get(), &result);
+  EXPECT_TRUE(result.proxy_server().is_direct());
+  EXPECT_EQ(result.config_id(), prev_id);
+
+  // Test that ws:// and wss:// URLs bypass the data reduction proxy.
+  result.UseDirect();
+  OnResolveProxyHandler(GURL("ws://echo.websocket.org/"),
+                        load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(), &result);
+  EXPECT_TRUE(result.is_direct());
+
+  OnResolveProxyHandler(GURL("wss://echo.websocket.org/"),
+                        load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(), &result);
+  EXPECT_TRUE(result.is_direct());
+
+  // Without DataCompressionProxyCriticalBypass Finch trial set, the
+  // BYPASS_DATA_REDUCTION_PROXY load flag should be ignored.
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(),
+                        &result);
+  EXPECT_FALSE(result.is_direct());
+
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info,
+                        params_.get(), &other_proxy_info);
+  EXPECT_FALSE(other_proxy_info.is_direct());
+
+  load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
+
+  result.UseDirect();
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(),
+                        &result);
+  EXPECT_FALSE(result.is_direct());
+
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info,
+                        params_.get(), &other_proxy_info);
+  EXPECT_FALSE(other_proxy_info.is_direct());
+
+  // With Finch trial set, should only bypass if LOAD flag is set and the
+  // effective proxy is the data compression proxy.
+  base::FieldTrialList field_trial_list(new BadEntropyProvider());
+  base::FieldTrialList::CreateFieldTrial("DataCompressionProxyCriticalBypass",
+                                         "Enabled");
+  EXPECT_TRUE(
+      DataReductionProxyParams::IsIncludedInCriticalPathBypassFieldTrial());
+
+  load_flags = net::LOAD_NORMAL;
+
+  result.UseDirect();
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(),
+                        &result);
+  EXPECT_FALSE(result.is_direct());
+
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(),
+                        &other_proxy_info);
+  EXPECT_FALSE(other_proxy_info.is_direct());
+
+  load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
+
+  result.UseDirect();
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(),
+                        &result);
+  EXPECT_TRUE(result.is_direct());
+
+  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
+                        empty_proxy_retry_info, params_.get(),
+                        &other_proxy_info);
+  EXPECT_FALSE(other_proxy_info.is_direct());
+}
+
+TEST_F(DataReductionProxyNetworkDelegateTest, TotalLengths) {
+  const int64 kOriginalLength = 200;
+  const int64 kReceivedLength = 100;
+
+  TestingPrefServiceSimple pref_service;
+  scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs(
+      new DataReductionProxyStatisticsPrefs(
+          &pref_service,
+          scoped_refptr<base::TestSimpleTaskRunner>(
+              new base::TestSimpleTaskRunner()),
+          base::TimeDelta()));
+  PrefRegistrySimple* registry = pref_service.registry();
+  data_reduction_proxy::RegisterSimpleProfilePrefs(registry);
+
+  data_reduction_proxy_network_delegate_->
+      data_reduction_proxy_statistics_prefs_ =
+          statistics_prefs->GetWeakPtr();
+
+  data_reduction_proxy_network_delegate_->UpdateContentLengthPrefs(
+      kReceivedLength, kOriginalLength,
+      pref_service.GetBoolean(
+          data_reduction_proxy::prefs::kDataReductionProxyEnabled),
+      UNKNOWN_TYPE);
+
+  EXPECT_EQ(kReceivedLength,
+            statistics_prefs->GetInt64(
+                data_reduction_proxy::prefs::kHttpReceivedContentLength));
+  EXPECT_FALSE(pref_service.GetBoolean(
+      data_reduction_proxy::prefs::kDataReductionProxyEnabled));
+  EXPECT_EQ(kOriginalLength,
+            statistics_prefs->GetInt64(
+                data_reduction_proxy::prefs::kHttpOriginalContentLength));
+
+  // Record the same numbers again, and total lengths should be doubled.
+  data_reduction_proxy_network_delegate_->UpdateContentLengthPrefs(
+      kReceivedLength, kOriginalLength,
+      pref_service.GetBoolean(
+          data_reduction_proxy::prefs::kDataReductionProxyEnabled),
+      UNKNOWN_TYPE);
+
+  EXPECT_EQ(kReceivedLength * 2,
+            statistics_prefs->GetInt64(
+                data_reduction_proxy::prefs::kHttpReceivedContentLength));
+  EXPECT_FALSE(pref_service.GetBoolean(
+      data_reduction_proxy::prefs::kDataReductionProxyEnabled));
+  EXPECT_EQ(kOriginalLength * 2,
+            statistics_prefs->GetInt64(
+                data_reduction_proxy::prefs::kHttpOriginalContentLength));
+}
+
 class DataReductionProxyHistoricNetworkStatsTest
     : public testing::Test {
  public:
-  DataReductionProxyHistoricNetworkStatsTest() {}
+  DataReductionProxyHistoricNetworkStatsTest() {
+  }
 
   void SetUp() override {
     simple_pref_service_.registry()->RegisterInt64Pref(
@@ -313,163 +524,4 @@
   VerifyPrefs(dict);
 }
 
-class BadEntropyProvider : public base::FieldTrial::EntropyProvider {
- public:
-  ~BadEntropyProvider() override {}
-
-  double GetEntropyForTrial(const std::string& trial_name,
-                            uint32 randomization_seed) const override {
-    return 0.5;
-  }
-};
-
-TEST_F(DataReductionProxyNetworkDelegateTest, OnResolveProxyHandler) {
-  int load_flags = net::LOAD_NORMAL;
-  GURL url("http://www.google.com/");
-
-  TestDataReductionProxyParams test_params(
-            DataReductionProxyParams::kAllowed |
-            DataReductionProxyParams::kFallbackAllowed |
-            DataReductionProxyParams::kPromoAllowed,
-            TestDataReductionProxyParams::HAS_EVERYTHING &
-            ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-            ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN);
-
-  // Data reduction proxy info
-  net::ProxyInfo data_reduction_proxy_info;
-  std::string data_reduction_proxy;
-  base::TrimString(test_params.DefaultOrigin(), "/", &data_reduction_proxy);
-  data_reduction_proxy_info.UsePacString(
-      "PROXY " +
-      net::HostPortPair::FromURL(GURL(test_params.DefaultOrigin())).ToString() +
-      "; DIRECT");
-  EXPECT_FALSE(data_reduction_proxy_info.is_empty());
-
-  // Data reduction proxy config
-  net::ProxyConfig data_reduction_proxy_config;
-  data_reduction_proxy_config.proxy_rules().ParseFromString(
-      "http=" + data_reduction_proxy + ",direct://;");
-  data_reduction_proxy_config.set_id(1);
-
-  // Other proxy info
-  net::ProxyInfo other_proxy_info;
-  other_proxy_info.UseNamedProxy("proxy.com");
-  EXPECT_FALSE(other_proxy_info.is_empty());
-
-  // Direct
-  net::ProxyInfo direct_proxy_info;
-  direct_proxy_info.UseDirect();
-  EXPECT_TRUE(direct_proxy_info.is_direct());
-
-  // Empty retry info map
-  net::ProxyRetryInfoMap empty_proxy_retry_info;
-
-  // Retry info map with the data reduction proxy;
-  net::ProxyRetryInfoMap data_reduction_proxy_retry_info;
-  net::ProxyRetryInfo retry_info;
-  retry_info.current_delay = base::TimeDelta::FromSeconds(1000);
-  retry_info.bad_until = base::TimeTicks().Now() + retry_info.current_delay;
-  retry_info.try_while_bad = false;
-  data_reduction_proxy_retry_info[
-     data_reduction_proxy_info.proxy_server().ToURI()] = retry_info;
-
-  net::ProxyInfo result;
-  // Another proxy is used. It should be used afterwards.
-  result.Use(other_proxy_info);
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                       empty_proxy_retry_info, &test_params, &result);
-  EXPECT_EQ(other_proxy_info.proxy_server(), result.proxy_server());
-
-  // A direct connection is used. The data reduction proxy should be used
-  // afterwards.
-  // Another proxy is used. It should be used afterwards.
-  result.Use(direct_proxy_info);
-  net::ProxyConfig::ID prev_id = result.config_id();
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                       empty_proxy_retry_info, &test_params, &result);
-  EXPECT_EQ(data_reduction_proxy_info.proxy_server(), result.proxy_server());
-  // Only the proxy list should be updated, not he proxy info.
-  EXPECT_EQ(result.config_id(), prev_id);
-
-  // A direct connection is used, but the data reduction proxy is on the retry
-  // list. A direct connection should be used afterwards.
-  result.Use(direct_proxy_info);
-  prev_id = result.config_id();
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                       data_reduction_proxy_retry_info, &test_params, &result);
-  EXPECT_TRUE(result.proxy_server().is_direct());
-  EXPECT_EQ(result.config_id(), prev_id);
-
-  // Test that ws:// and wss:// URLs bypass the data reduction proxy.
-  result.UseDirect();
-  OnResolveProxyHandler(GURL("ws://echo.websocket.org/"),
-                       load_flags, data_reduction_proxy_config,
-                       empty_proxy_retry_info, &test_params, &result);
-  EXPECT_TRUE(result.is_direct());
-
-  OnResolveProxyHandler(GURL("wss://echo.websocket.org/"),
-                       load_flags, data_reduction_proxy_config,
-                       empty_proxy_retry_info, &test_params, &result);
-  EXPECT_TRUE(result.is_direct());
-
-  // Without DataCompressionProxyCriticalBypass Finch trial set, the
-  // BYPASS_DATA_REDUCTION_PROXY load flag should be ignored.
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info, &test_params,
-                        &result);
-  EXPECT_FALSE(result.is_direct());
-
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info,
-                        &test_params, &other_proxy_info);
-  EXPECT_FALSE(other_proxy_info.is_direct());
-
-  load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
-
-  result.UseDirect();
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info, &test_params,
-                        &result);
-  EXPECT_FALSE(result.is_direct());
-
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info,
-                        &test_params, &other_proxy_info);
-  EXPECT_FALSE(other_proxy_info.is_direct());
-
-  // With Finch trial set, should only bypass if LOAD flag is set and the
-  // effective proxy is the data compression proxy.
-  base::FieldTrialList field_trial_list(new BadEntropyProvider());
-  base::FieldTrialList::CreateFieldTrial("DataCompressionProxyCriticalBypass",
-                                         "Enabled");
-  EXPECT_TRUE(
-      DataReductionProxyParams::IsIncludedInCriticalPathBypassFieldTrial());
-
-  load_flags = net::LOAD_NORMAL;
-
-  result.UseDirect();
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info, &test_params,
-                        &result);
-  EXPECT_FALSE(result.is_direct());
-
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info, &test_params,
-                        &other_proxy_info);
-  EXPECT_FALSE(other_proxy_info.is_direct());
-
-  load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
-
-  result.UseDirect();
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info, &test_params,
-                        &result);
-  EXPECT_TRUE(result.is_direct());
-
-  OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config,
-                        empty_proxy_retry_info, &test_params,
-                        &other_proxy_info);
-  EXPECT_FALSE(other_proxy_info.is_direct());
-}
-
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
index 6db2391..7dfba16 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -127,14 +127,17 @@
 
 void DataReductionProxySettings::InitDataReductionProxySettings(
     PrefService* prefs,
+    scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs,
     net::URLRequestContextGetter* url_request_context_getter,
     net::NetLog* net_log,
     DataReductionProxyEventStore* event_store) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(prefs);
+  DCHECK(!statistics_prefs_);
   DCHECK(url_request_context_getter);
   DCHECK(event_store);
   prefs_ = prefs;
+  statistics_prefs_ = statistics_prefs.Pass();
   url_request_context_getter_ = url_request_context_getter;
   net_log_ = net_log;
   event_store_ = event_store;
@@ -150,8 +153,25 @@
 }
 
 void DataReductionProxySettings::SetDataReductionProxyStatisticsPrefs(
-    DataReductionProxyStatisticsPrefs* statistics_prefs) {
-  statistics_prefs_ = statistics_prefs;
+    scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs) {
+  statistics_prefs_ = statistics_prefs.Pass();
+}
+
+void DataReductionProxySettings::EnableCompressionStatisticsLogging(
+    PrefService* prefs,
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    const base::TimeDelta& commit_delay) {
+  DCHECK(!statistics_prefs_);
+  statistics_prefs_.reset(
+      new DataReductionProxyStatisticsPrefs(
+          prefs, ui_task_runner, commit_delay));
+}
+
+base::WeakPtr<DataReductionProxyStatisticsPrefs>
+DataReductionProxySettings::statistics_prefs() {
+  if (statistics_prefs_)
+    return statistics_prefs_->GetWeakPtr();
+  return base::WeakPtr<DataReductionProxyStatisticsPrefs>();
 }
 
 void DataReductionProxySettings::SetOnDataReductionEnabledCallback(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
index 3608f97..2eda652 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
@@ -35,6 +35,7 @@
 namespace data_reduction_proxy {
 
 class DataReductionProxyEventStore;
+class DataReductionProxyStatisticsPrefs;
 
 // The number of days of bandwidth usage statistics that are tracked.
 const unsigned int kNumDaysInHistory = 60;
@@ -108,14 +109,19 @@
   // |DataReductionProxySettings| instance.
   void InitDataReductionProxySettings(
       PrefService* prefs,
+      scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs,
       net::URLRequestContextGetter* url_request_context_getter,
       net::NetLog* net_log,
       DataReductionProxyEventStore* event_store);
 
-  // Sets the |statistics_prefs_| to be used for data reduction proxy pref reads
-  // and writes.
-  void SetDataReductionProxyStatisticsPrefs(
-      DataReductionProxyStatisticsPrefs* statistics_prefs);
+  // Constructs statistics prefs. This should not be called if a valid
+  // statistics prefs is passed into the constructor.
+  void EnableCompressionStatisticsLogging(
+      PrefService* prefs,
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+      const base::TimeDelta& commit_delay);
+
+  base::WeakPtr<DataReductionProxyStatisticsPrefs> statistics_prefs();
 
   // Sets the |on_data_reduction_proxy_enabled_| callback and runs to register
   // the DataReductionProxyEnabled synthetic field trial.
@@ -188,6 +194,10 @@
     return event_store_;
   }
 
+  // Used for testing.
+  void SetDataReductionProxyStatisticsPrefs(
+      scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs);
+
  protected:
   void InitPrefMembers();
 
@@ -311,7 +321,7 @@
   BooleanPrefMember data_reduction_proxy_alternative_enabled_;
 
   PrefService* prefs_;
-  DataReductionProxyStatisticsPrefs* statistics_prefs_;
+  scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs_;
 
   net::URLRequestContextGetter* url_request_context_getter_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
index 18f8740..d1017ef 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -99,11 +99,6 @@
   registry->RegisterBooleanPref(prefs::kDataReductionProxyWasEnabledBefore,
                                 false);
 
-  statistics_prefs_.reset(new DataReductionProxyStatisticsPrefs(
-      &pref_service_,
-      scoped_refptr<base::TestSimpleTaskRunner>(
-          new base::TestSimpleTaskRunner()),
-          base::TimeDelta()));
   event_store_.reset(new DataReductionProxyEventStore(
       scoped_refptr<base::TestSimpleTaskRunner>(
           new base::TestSimpleTaskRunner())));
@@ -121,9 +116,17 @@
     received_update->Insert(0, new base::StringValue(base::Int64ToString(i)));
   }
   last_update_time_ = base::Time::Now().LocalMidnight();
-  statistics_prefs_->SetInt64(
+  scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs(
+      new DataReductionProxyStatisticsPrefs(
+          &pref_service_,
+          scoped_refptr<base::TestSimpleTaskRunner>(
+              new base::TestSimpleTaskRunner()),
+              base::TimeDelta()));
+  statistics_prefs->SetInt64(
       prefs::kDailyHttpContentLengthLastUpdateDate,
       last_update_time_.ToInternalValue());
+  settings_->SetDataReductionProxyStatisticsPrefs(
+        statistics_prefs.Pass());
   expected_params_.reset(new TestDataReductionProxyParams(
       DataReductionProxyParams::kAllowed |
       DataReductionProxyParams::kFallbackAllowed |
@@ -165,7 +168,6 @@
       scoped_refptr<base::TestSimpleTaskRunner>(
           new base::TestSimpleTaskRunner()), &net_log_, event_store_.get()));
   settings_->configurator_ = configurator_.get();
-  settings_->SetDataReductionProxyStatisticsPrefs(statistics_prefs_.get());
 }
 
 // Explicitly generate required instantiations.
@@ -299,8 +301,13 @@
   scoped_refptr<net::TestURLRequestContextGetter> request_context =
       new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
 
+  // Delete statistics prefs, otherwise the DCHECK in
+  // InitDataReductionProxySettings fails.
+  settings_->SetDataReductionProxyStatisticsPrefs(
+      scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>());
   settings_->InitDataReductionProxySettings(
       &pref_service_,
+      scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>(),
       request_context.get(),
       &net_log_,
       event_store_.get());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
index ccd8170..1465d4f9 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.h
@@ -159,6 +159,7 @@
                             bool expected_enabled,
                             bool expected_fallback_restricted);
   void CheckOnPrefChange(bool enabled, bool expected_enabled, bool managed);
+  void InitWithStatisticsPrefs();
   void CheckInitDataReductionProxy(bool enabled_at_startup);
   void RegisterSyntheticFieldTrialCallback(bool proxy_enabled) {
     proxy_enabled_ = proxy_enabled;
@@ -170,7 +171,6 @@
   scoped_ptr<TestDataReductionProxyParams> expected_params_;
   base::Time last_update_time_;
   bool proxy_enabled_;
-  scoped_ptr<DataReductionProxyStatisticsPrefs> statistics_prefs_;
   net::CapturingNetLog net_log_;
   scoped_ptr<DataReductionProxyEventStore> event_store_;
 };
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
index 307fb50..571753bb 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -29,6 +29,8 @@
 
 namespace data_reduction_proxy {
 
+class DataReductionProxyStatisticsPrefs;
+
 class DataReductionProxySettingsTest
     : public ConcreteDataReductionProxySettingsTest<
           DataReductionProxySettings> {
@@ -419,6 +421,7 @@
       new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
   settings_->InitDataReductionProxySettings(
       &pref_service_,
+      scoped_ptr<DataReductionProxyStatisticsPrefs>(),
       request_context.get(),
       &net_log_,
       event_store_.get());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.cc
index 93d2320..1b28d5d7 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.cc
@@ -33,12 +33,8 @@
 }
 
 DataReductionProxyStatisticsPrefs::~DataReductionProxyStatisticsPrefs() {
-  // This object is created on UI thread, but destroyed on IO thread. So no
-  // DCHECK on thread_checker_ here.
-}
-
-void DataReductionProxyStatisticsPrefs::ShutdownOnUIThread() {
   DCHECK(thread_checker_.CalledOnValidThread());
+  WritePrefs();
   pref_change_registrar_->RemoveAll();
   weak_factory_.InvalidateWeakPtrs();
 }
@@ -77,7 +73,7 @@
   pref_change_registrar_->Init(pref_service_);
   pref_change_registrar_->Add(prefs::kUpdateDailyReceivedContentLengths,
       base::Bind(&DataReductionProxyStatisticsPrefs::OnUpdateContentLengths,
-                                         weak_factory_.GetWeakPtr()));
+                 GetWeakPtr()));
 }
 
 void DataReductionProxyStatisticsPrefs::OnUpdateContentLengths() {
@@ -155,7 +151,7 @@
   task_runner_->PostDelayedTask(
       FROM_HERE,
       base::Bind(&DataReductionProxyStatisticsPrefs::WritePrefs,
-                 weak_factory_.GetWeakPtr()),
+                 GetWeakPtr()),
                  delay_);
 
   delayed_task_posted_ = true;
@@ -186,4 +182,9 @@
   return value;
 }
 
+base::WeakPtr<DataReductionProxyStatisticsPrefs>
+DataReductionProxyStatisticsPrefs::GetWeakPtr() {
+  return weak_factory_.GetWeakPtr();
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h
index 04e1947..995559b3 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h
@@ -47,8 +47,6 @@
   // |list_pref_map_|.
   void Init();
 
-  void ShutdownOnUIThread();
-
   void OnUpdateContentLengths();
 
   // Gets the int64 pref at |pref_path| from the |DataReductionProxyPrefMap|.
@@ -65,6 +63,8 @@
   // |DataReductionProxyListPrefMap| to |pref_service|.
   void WritePrefs();
 
+  base::WeakPtr<DataReductionProxyStatisticsPrefs> GetWeakPtr();
+
 private:
   typedef std::map<const char*, int64> DataReductionProxyPrefMap;
   typedef base::ScopedPtrHashMap<const char*, base::ListValue>