summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkundaji@chromium.org <kundaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-25 04:36:20 +0000
committerkundaji@chromium.org <kundaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-25 04:36:20 +0000
commitbceab7f54c854090b4264ba128bf8f70d0476912 (patch)
treed789f6702bec91598268b342dd37c04019f3c8f2
parent9c388be0afa0ec9d7d177f54faaab9e77deda954 (diff)
downloadchromium_src-bceab7f54c854090b4264ba128bf8f70d0476912.zip
chromium_src-bceab7f54c854090b4264ba128bf8f70d0476912.tar.gz
chromium_src-bceab7f54c854090b4264ba128bf8f70d0476912.tar.bz2
Display an error message on usage settings page when proxy cannot be contacted.
Add data_reduction_proxy_usage_stats which keeps track of number of requests completed through data reduction proxy vs number of requests eligible to use data reduction proxy. Instantiate and set on io thread globals so that we can pass it to chrome network delegate. Expose isDataReductionProxyUnreachable() method to Android code through DataReductionProxySettings where it will be used to decide whether to display the unreachable proxy message. BUG=380195 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=279222 Review URL: https://codereview.chromium.org/338273003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279583 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java10
-rw-r--r--chrome/browser/io_thread.cc15
-rw-r--r--chrome/browser/io_thread.h3
-rw-r--r--chrome/browser/net/chrome_network_delegate.cc7
-rw-r--r--chrome/browser/net/chrome_network_delegate.h15
-rw-r--r--chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc6
-rw-r--r--chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h5
-rw-r--r--chrome/browser/profiles/profile_io_data.cc43
-rw-r--r--chrome/browser/profiles/profile_io_data.h10
-rw-r--r--components/components_tests.gyp1
-rw-r--r--components/data_reduction_proxy.gypi2
-rw-r--r--components/data_reduction_proxy/browser/data_reduction_proxy_params.cc20
-rw-r--r--components/data_reduction_proxy/browser/data_reduction_proxy_params.h5
-rw-r--r--components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc11
-rw-r--r--components/data_reduction_proxy/browser/data_reduction_proxy_settings.h15
-rw-r--r--components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.cc98
-rw-r--r--components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h71
-rw-r--r--components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats_unittest.cc105
18 files changed, 437 insertions, 5 deletions
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java
index 4444a6f..f5aa307 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java
@@ -179,6 +179,14 @@ public class DataReductionProxySettings {
}
/**
+ * Determines if the data reduction proxy is currently unreachable.
+ * @return true if the data reduction proxy is unreachable.
+ */
+ public boolean isDataReductionProxyUnreachable() {
+ return nativeIsDataReductionProxyUnreachable(mNativeDataReductionProxySettings);
+ }
+
+ /**
* @return The data reduction settings as a string percentage.
*/
public String getContentLengthPercentSavings() {
@@ -221,4 +229,6 @@ public class DataReductionProxySettings {
long nativeDataReductionProxySettingsAndroid);
private native long[] nativeGetDailyReceivedContentLengths(
long nativeDataReductionProxySettingsAndroid);
+ private native boolean nativeIsDataReductionProxyUnreachable(
+ long nativeDataReductionProxySettingsAndroid);
}
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 0ae0aa0..19880aa 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -106,6 +106,7 @@ using content::BrowserThread;
#if defined(OS_ANDROID) || defined(OS_IOS)
using data_reduction_proxy::DataReductionProxyParams;
+using data_reduction_proxy::DataReductionProxyUsageStats;
using data_reduction_proxy::DataReductionProxySettings;
#endif
@@ -608,10 +609,16 @@ void IOThread::InitAsync() {
drp_flags |= DataReductionProxyParams::kAlternativeAllowed;
if (DataReductionProxyParams::IsIncludedInPromoFieldTrial())
drp_flags |= DataReductionProxyParams::kPromoAllowed;
- globals_->data_reduction_proxy_params.reset(
- new DataReductionProxyParams(drp_flags));
- network_delegate->set_data_reduction_proxy_params(
- globals_->data_reduction_proxy_params.get());
+ DataReductionProxyParams* proxy_params =
+ new DataReductionProxyParams(drp_flags);
+ globals_->data_reduction_proxy_params.reset(proxy_params);
+ network_delegate->set_data_reduction_proxy_params(proxy_params);
+ DataReductionProxyUsageStats* proxy_usage_stats =
+ new DataReductionProxyUsageStats(proxy_params,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
+ globals_->data_reduction_proxy_usage_stats.reset(proxy_usage_stats);
+ network_delegate->set_data_reduction_proxy_usage_stats(proxy_usage_stats);
#endif // defined(SPDY_PROXY_AUTH_ORIGIN)
#endif // defined(OS_ANDROID) || defined(OS_IOS)
globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index 2daf2be..2fc953f 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -17,6 +17,7 @@
#include "base/time/time.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browser_thread_delegate.h"
#include "net/base/network_change_notifier.h"
@@ -185,6 +186,8 @@ class IOThread : public content::BrowserThreadDelegate {
scoped_ptr<chrome_browser_net::DnsProbeService> dns_probe_service;
scoped_ptr<data_reduction_proxy::DataReductionProxyParams>
data_reduction_proxy_params;
+ scoped_ptr<data_reduction_proxy::DataReductionProxyUsageStats>
+ data_reduction_proxy_usage_stats;
};
// |net_log| must either outlive the IOThread or be NULL.
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 89bb50a..2f1af206 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -34,6 +34,7 @@
#include "components/data_reduction_proxy/browser/data_reduction_proxy_metrics.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_protocol.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
#include "components/domain_reliability/monitor.h"
#include "components/google/core/browser/google_util.h"
#include "content/public/browser/browser_thread.h"
@@ -296,7 +297,8 @@ ChromeNetworkDelegate::ChromeNetworkDelegate(
original_content_length_(0),
first_request_(true),
prerender_tracker_(NULL),
- data_reduction_proxy_params_(NULL) {
+ data_reduction_proxy_params_(NULL),
+ data_reduction_proxy_usage_stats_(NULL) {
DCHECK(enable_referrers);
extensions_delegate_.reset(
ChromeExtensionsNetworkDelegate::Create(event_router));
@@ -534,6 +536,9 @@ void ChromeNetworkDelegate::OnRawBytesRead(const net::URLRequest& request,
void ChromeNetworkDelegate::OnCompleted(net::URLRequest* request,
bool started) {
+ if (data_reduction_proxy_usage_stats_)
+ data_reduction_proxy_usage_stats_->OnUrlRequestCompleted(request, started);
+
TRACE_EVENT_ASYNC_END0("net", "URLRequest", request);
if (request->status().status() == net::URLRequestStatus::SUCCESS) {
// For better accuracy, we use the actual bytes read instead of the length
diff --git a/chrome/browser/net/chrome_network_delegate.h b/chrome/browser/net/chrome_network_delegate.h
index a67f773..4aee027 100644
--- a/chrome/browser/net/chrome_network_delegate.h
+++ b/chrome/browser/net/chrome_network_delegate.h
@@ -20,6 +20,7 @@ class ChromeExtensionsNetworkDelegate;
class ClientHints;
class CookieSettings;
class PrefService;
+
template<class T> class PrefMember;
typedef PrefMember<bool> BooleanPrefMember;
@@ -35,6 +36,7 @@ class Predictor;
namespace data_reduction_proxy {
class DataReductionProxyParams;
+class DataReductionProxyUsageStats;
}
namespace domain_reliability {
@@ -118,11 +120,19 @@ class ChromeNetworkDelegate : public net::NetworkDelegate {
prerender_tracker_ = prerender_tracker;
}
+ // |data_reduction_proxy_params_| must outlive this ChromeNetworkDelegate.
void set_data_reduction_proxy_params(
data_reduction_proxy::DataReductionProxyParams* params) {
data_reduction_proxy_params_ = params;
}
+ // |data_reduction_proxy_usage_stats_| must outlive this
+ // ChromeNetworkDelegate.
+ void set_data_reduction_proxy_usage_stats(
+ data_reduction_proxy::DataReductionProxyUsageStats* usage_stats) {
+ data_reduction_proxy_usage_stats_ = usage_stats;
+ }
+
// Adds the Client Hints header to HTTP requests.
void SetEnableClientHints();
@@ -248,7 +258,12 @@ class ChromeNetworkDelegate : public net::NetworkDelegate {
prerender::PrerenderTracker* prerender_tracker_;
+ // |data_reduction_proxy_params_| must outlive this ChromeNetworkDelegate.
data_reduction_proxy::DataReductionProxyParams* data_reduction_proxy_params_;
+ // |data_reduction_proxy_usage_stats_| must outlive this
+ // ChromeNetworkDelegate.
+ data_reduction_proxy::DataReductionProxyUsageStats*
+ data_reduction_proxy_usage_stats_;
DISALLOW_COPY_AND_ASSIGN(ChromeNetworkDelegate);
};
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
index 211ff61..695a4f4 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc
@@ -191,6 +191,12 @@ DataReductionProxySettingsAndroid::GetDailyReceivedContentLengths(
env, data_reduction_proxy::prefs::kDailyHttpReceivedContentLength);
}
+jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyUnreachable(
+ JNIEnv* env, jobject obj) {
+ DCHECK(usage_stats());
+ return usage_stats()->isDataReductionProxyUnreachable();
+}
+
// static
bool DataReductionProxySettingsAndroid::Register(JNIEnv* env) {
bool register_natives_impl_result = RegisterNativesImpl(env);
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h
index 7df436f..f69b6d1 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h
@@ -75,6 +75,11 @@ class DataReductionProxySettingsAndroid
jstring host,
jstring realm);
+ // Determines whether the data reduction proxy is unreachable. This is
+ // done by keeping a count of requests which go through proxy vs those
+ // which should have gone through the proxy based on the config.
+ jboolean IsDataReductionProxyUnreachable(JNIEnv* env, jobject obj);
+
ScopedJavaLocalRef<jstring> GetTokenForAuthChallenge(JNIEnv* env,
jobject obj,
jstring host,
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index b47f92e..af33c44 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -94,6 +94,11 @@
#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
#endif
+#if defined(OS_ANDROID)
+#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h"
+#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_factory_android.h"
+#endif // defined(OS_ANDROID)
+
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/drive/drive_protocol_handler.h"
#include "chrome/browser/chromeos/login/startup_utils.h"
@@ -129,6 +134,7 @@
using content::BrowserContext;
using content::BrowserThread;
using content::ResourceContext;
+using data_reduction_proxy::DataReductionProxyUsageStats;
namespace {
@@ -470,12 +476,47 @@ void ProfileIOData::InitializeOnUIThread(Profile* profile) {
initialized_on_UI_thread_ = true;
+#if defined(OS_ANDROID)
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&ProfileIOData::SetDataReductionProxyUsageStatsOnIOThread,
+ base::Unretained(this), g_browser_process->io_thread(), profile));
+#endif
+#endif
+
// We need to make sure that content initializes its own data structures that
// are associated with each ResourceContext because we might post this
// object to the IO thread after this function.
BrowserContext::EnsureResourceContextInitialized(profile);
}
+#if defined(OS_ANDROID)
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+void ProfileIOData::SetDataReductionProxyUsageStatsOnIOThread(
+ IOThread* io_thread, Profile* profile) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ IOThread::Globals* globals = io_thread->globals();
+ DataReductionProxyUsageStats* usage_stats =
+ globals->data_reduction_proxy_usage_stats.get();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&ProfileIOData::SetDataReductionProxyUsageStatsOnUIThread,
+ base::Unretained(this), profile, usage_stats));
+}
+
+void ProfileIOData::SetDataReductionProxyUsageStatsOnUIThread(
+ Profile* profile,
+ DataReductionProxyUsageStats* usage_stats) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (g_browser_process->profile_manager()->IsValidProfile(profile)) {
+ DataReductionProxySettingsAndroid* proxySettingsAndroid =
+ DataReductionProxySettingsFactoryAndroid::GetForBrowserContext(profile);
+ if (proxySettingsAndroid)
+ proxySettingsAndroid->SetDataReductionProxyUsageStats(usage_stats);
+ }
+}
+#endif
+#endif
+
ProfileIOData::MediaRequestContext::MediaRequestContext() {
}
@@ -942,6 +983,8 @@ void ProfileIOData::Init(
&enable_referrers_);
network_delegate->set_data_reduction_proxy_params(
io_thread_globals->data_reduction_proxy_params.get());
+ network_delegate->set_data_reduction_proxy_usage_stats(
+ io_thread_globals->data_reduction_proxy_usage_stats.get());
if (command_line.HasSwitch(switches::kEnableClientHints))
network_delegate->SetEnableClientHints();
network_delegate->set_extension_info_map(
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index bbe1ace..540d5dd 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -21,6 +21,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/storage_partition_descriptor.h"
#include "chrome/common/content_settings_types.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_context.h"
#include "net/cookies/cookie_monster.h"
@@ -324,6 +325,15 @@ class ProfileIOData {
void InitializeOnUIThread(Profile* profile);
void ApplyProfileParamsToContext(ChromeURLRequestContext* context) const;
+#if defined(OS_ANDROID)
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+ void SetDataReductionProxyUsageStatsOnIOThread(IOThread* io_thread,
+ Profile* profile);
+ void SetDataReductionProxyUsageStatsOnUIThread(Profile* profile,
+ data_reduction_proxy::DataReductionProxyUsageStats* usage_stats);
+#endif
+#endif
+
scoped_ptr<net::URLRequestJobFactory> SetUpJobFactoryDefaults(
scoped_ptr<net::URLRequestJobFactoryImpl> job_factory,
content::URLRequestInterceptorScopedVector request_interceptors,
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 96de79b..2d16857 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -78,6 +78,7 @@
'data_reduction_proxy/browser/data_reduction_proxy_params_unittest.cc',
'data_reduction_proxy/browser/data_reduction_proxy_protocol_unittest.cc',
'data_reduction_proxy/browser/data_reduction_proxy_settings_unittest.cc',
+ 'data_reduction_proxy/browser/data_reduction_proxy_usage_stats_unittest.cc',
'data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy_unittest.cc',
'data_reduction_proxy/common/data_reduction_proxy_headers_unittest.cc',
'dom_distiller/core/article_entry_unittest.cc',
diff --git a/components/data_reduction_proxy.gypi b/components/data_reduction_proxy.gypi
index de00304..892620a 100644
--- a/components/data_reduction_proxy.gypi
+++ b/components/data_reduction_proxy.gypi
@@ -34,6 +34,8 @@
'data_reduction_proxy/browser/data_reduction_proxy_protocol.h',
'data_reduction_proxy/browser/data_reduction_proxy_settings.cc',
'data_reduction_proxy/browser/data_reduction_proxy_settings.h',
+ 'data_reduction_proxy/browser/data_reduction_proxy_usage_stats.cc',
+ 'data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h',
'data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.cc',
'data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h',
],
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_params.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_params.cc
index ce69157..708f0fd 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_params.cc
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_params.cc
@@ -7,7 +7,10 @@
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
using base::FieldTrialList;
@@ -277,6 +280,23 @@ bool DataReductionProxyParams::IsDataReductionProxy(
return false;
}
+// TODO(kundaji): Check that the request will actually be sent through the
+// proxy.
+bool DataReductionProxyParams::IsDataReductionProxyEligible(
+ const net::URLRequest* request) {
+ DCHECK(request);
+ DCHECK(request->context());
+ DCHECK(request->context()->proxy_service());
+ net::ProxyInfo result;
+ request->context()->proxy_service()->config().proxy_rules().Apply(
+ request->url(), &result);
+ if (!result.proxy_server().is_valid())
+ return false;
+ if (result.proxy_server().is_direct())
+ return false;
+ return IsDataReductionProxy(result.proxy_server().host_port_pair(), NULL);
+}
+
std::string DataReductionProxyParams::GetDefaultKey() const {
#if defined(SPDY_PROXY_AUTH_VALUE)
return SPDY_PROXY_AUTH_VALUE;
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_params.h b/components/data_reduction_proxy/browser/data_reduction_proxy_params.h
index 5ae00b8..53f431c 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_params.h
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_params.h
@@ -88,6 +88,11 @@ class DataReductionProxyParams {
bool IsDataReductionProxy(const net::HostPortPair& host_port_pair,
std::pair<GURL, GURL>* proxy_servers) const;
+ // Returns true if this request will be sent through the data request proxy
+ // based on applying the param rules to the URL. We do not check bad proxy
+ // list.
+ virtual bool IsDataReductionProxyEligible(const net::URLRequest* request);
+
// Returns the data reduction proxy primary origin.
const GURL& origin() const {
return origin_;
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc
index dc87a52..0067d8e 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.cc
@@ -17,6 +17,7 @@
#include "base/strings/utf_string_conversions.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
#include "components/data_reduction_proxy/common/data_reduction_proxy_pref_names.h"
#include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h"
#include "crypto/random.h"
@@ -295,6 +296,16 @@ DataReductionProxySettings::GetDailyOriginalContentLengths() {
return GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength);
}
+bool DataReductionProxySettings::IsDataReductionProxyUnreachable() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return usage_stats_->isDataReductionProxyUnreachable();
+}
+
+void DataReductionProxySettings::SetDataReductionProxyUsageStats(
+ DataReductionProxyUsageStats* usage_stats) {
+ usage_stats_ = usage_stats;
+}
+
DataReductionProxySettings::ContentLengthList
DataReductionProxySettings::GetDailyReceivedContentLengths() {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h
index eb68f67..e95705a 100644
--- a/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h
@@ -15,6 +15,7 @@
#include "base/threading/thread_checker.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
#include "net/base/network_change_notifier.h"
#include "net/url_request/url_fetcher_delegate.h"
@@ -97,6 +98,10 @@ class DataReductionProxySettings
return params_.get();
}
+ DataReductionProxyUsageStats* usage_stats() const {
+ return usage_stats_;
+ }
+
// Initializes the data reduction proxy with profile and local state prefs,
// and a |UrlRequestContextGetter| for canary probes. The caller must ensure
// that all parameters remain alive for the lifetime of the
@@ -163,6 +168,15 @@ class DataReductionProxySettings
// data reduction proxy. Each element in the vector contains one day of data.
ContentLengthList GetDailyOriginalContentLengths();
+ // Returns whether the data reduction proxy is unreachable. Returns true
+ // if no request has successfully completed through proxy, even though atleast
+ // some of them should have.
+ bool IsDataReductionProxyUnreachable();
+
+ // Set the data reduction proxy usage stats.
+ void SetDataReductionProxyUsageStats(
+ DataReductionProxyUsageStats* usage_stats);
+
// Returns an vector containing the aggregate received HTTP content in the
// last |kNumDaysInHistory| days.
ContentLengthList GetDailyReceivedContentLengths();
@@ -311,6 +325,7 @@ class DataReductionProxySettings
base::ThreadChecker thread_checker_;
scoped_ptr<DataReductionProxyParams> params_;
+ DataReductionProxyUsageStats* usage_stats_;
DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings);
};
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.cc
new file mode 100644
index 0000000..61a26f2
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.cc
@@ -0,0 +1,98 @@
+// Copyright 2014 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.
+
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
+#include "net/proxy/proxy_retry_info.h"
+#include "net/proxy/proxy_server.h"
+#include "net/proxy/proxy_service.h"
+#include "net/url_request/url_request_context.h"
+
+using base::MessageLoopProxy;
+using net::HostPortPair;
+using net::ProxyServer;
+using net::NetworkChangeNotifier;
+
+namespace data_reduction_proxy {
+
+DataReductionProxyUsageStats::DataReductionProxyUsageStats(
+ DataReductionProxyParams* params,
+ MessageLoopProxy* ui_thread_proxy,
+ MessageLoopProxy* io_thread_proxy)
+ : data_reduction_proxy_params_(params),
+ ui_thread_proxy_(ui_thread_proxy),
+ io_thread_proxy_(io_thread_proxy),
+ eligible_num_requests_through_proxy_(0),
+ actual_num_requests_through_proxy_(0) {
+ NetworkChangeNotifier::AddNetworkChangeObserver(this);
+};
+
+DataReductionProxyUsageStats::~DataReductionProxyUsageStats() {
+ NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+};
+
+void DataReductionProxyUsageStats::OnUrlRequestCompleted(
+ const net::URLRequest* request, bool started) {
+ DCHECK(io_thread_proxy_->BelongsToCurrentThread());
+
+ if (request->status().status() == net::URLRequestStatus::SUCCESS) {
+ if (data_reduction_proxy_params_->IsDataReductionProxyEligible(request)) {
+ bool was_received_via_proxy =
+ data_reduction_proxy_params_->WasDataReductionProxyUsed(
+ request, NULL);
+ ui_thread_proxy_->PostTask(FROM_HERE, base::Bind(
+ &DataReductionProxyUsageStats::IncRequestCountsOnUiThread,
+ base::Unretained(this), was_received_via_proxy));
+ }
+ }
+}
+
+/**
+ * Determines if the data reduction proxy is currently unreachable. We keep
+ * track of count of requests which go through data reduction proxy as well as
+ * count of requests which are eligible to go through the proxy. If and only if
+ * no requests go through proxy and some requests were eligible, we conclude
+ * that the proxy is unreachable.
+ *
+ * Returns true if the data reduction proxy is unreachable.
+ */
+bool DataReductionProxyUsageStats::isDataReductionProxyUnreachable() {
+ DCHECK(ui_thread_proxy_->BelongsToCurrentThread());
+
+ return eligible_num_requests_through_proxy_ > 0 &&
+ actual_num_requests_through_proxy_ == 0;
+}
+
+void DataReductionProxyUsageStats::OnNetworkChanged(
+ NetworkChangeNotifier::ConnectionType type) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ ui_thread_proxy_->PostTask(FROM_HERE, base::Bind(
+ &DataReductionProxyUsageStats::ClearRequestCountsOnUiThread,
+ base::Unretained(this)));
+}
+
+void DataReductionProxyUsageStats::IncRequestCountsOnUiThread(
+ bool was_received_via_proxy) {
+ DCHECK(ui_thread_proxy_->BelongsToCurrentThread());
+ if (was_received_via_proxy) {
+ actual_num_requests_through_proxy_++;
+ }
+ eligible_num_requests_through_proxy_++;
+
+ // To account for the case when the proxy works for a little while and then
+ // gets blocked, we reset the counts occasionally.
+ if (eligible_num_requests_through_proxy_ > 50
+ && actual_num_requests_through_proxy_ > 0) {
+ ClearRequestCountsOnUiThread();
+ }
+}
+
+void DataReductionProxyUsageStats::ClearRequestCountsOnUiThread() {
+ DCHECK(ui_thread_proxy_->BelongsToCurrentThread());
+ eligible_num_requests_through_proxy_ = 0;
+ actual_num_requests_through_proxy_ = 0;
+}
+
+} // namespace data_reduction_proxy
+
+
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h b/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h
new file mode 100644
index 0000000..6c217b2
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h
@@ -0,0 +1,71 @@
+// Copyright 2014 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 COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_USAGE_STATS_H_
+#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_USAGE_STATS_H_
+
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/threading/thread_checker.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/network_change_notifier.h"
+
+namespace data_reduction_proxy {
+
+class DataReductionProxyUsageStats
+ : public net::NetworkChangeNotifier::NetworkChangeObserver {
+ public:
+ // MessageLoopProxy instances are owned by io_thread. |params| outlives
+ // this class instance.
+ DataReductionProxyUsageStats(DataReductionProxyParams* params,
+ base::MessageLoopProxy* ui_thread_proxy,
+ base::MessageLoopProxy* io_thread_proxy);
+ virtual ~DataReductionProxyUsageStats();
+
+ /**
+ * Callback intended to be called from |ChromeNetworkDelegate| when a
+ * request completes. This method is used to gather usage stats.
+ */
+ void OnUrlRequestCompleted(const net::URLRequest* request, bool started);
+
+ /**
+ * Determines whether the data reduction proxy is unreachable.
+ * Returns true if data reduction proxy is unreachable.
+ */
+ bool isDataReductionProxyUnreachable();
+
+ private:
+ DataReductionProxyParams* data_reduction_proxy_params_;
+ base::MessageLoopProxy* ui_thread_proxy_;
+ base::MessageLoopProxy* io_thread_proxy_;
+
+ // The following 2 fields are used to determine if data reduction proxy is
+ // unreachable. We keep a count of requests which should go through
+ // data request proxy, as well as those which actually do. The proxy is
+ // unreachable if no successful requests are made through it despite a
+ // non-zero number of requests being eligible.
+
+ // Count of requests which will be tried to be sent through data reduction
+ // proxy. The count is only based on the config and not the bad proxy list.
+ // Explicit bypasses are not part of this count. This is the desired behavior
+ // since otherwise both counts would be identical.
+ unsigned long eligible_num_requests_through_proxy_;
+ // Count of successfull requests through data reduction proxy.
+ unsigned long actual_num_requests_through_proxy_;
+
+ // NetworkChangeNotifier::NetworkChangeObserver:
+ virtual void OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType type) OVERRIDE;
+
+ void IncRequestCountsOnUiThread(bool actual);
+ void ClearRequestCountsOnUiThread();
+
+ base::ThreadChecker thread_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataReductionProxyUsageStats);
+};
+
+} // namespace data_reduction_proxy
+
+#endif // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_USAGE_STATS_H_
diff --git a/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats_unittest.cc b/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats_unittest.cc
new file mode 100644
index 0000000..b20e90b
--- /dev/null
+++ b/components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats_unittest.cc
@@ -0,0 +1,105 @@
+// Copyright 2014 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.
+
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
+
+#include "net/base/request_priority.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_status.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::MessageLoop;
+using base::MessageLoopProxy;
+using data_reduction_proxy::DataReductionProxyParams;
+using net::TestDelegate;
+using net::TestURLRequestContext;
+using net::URLRequest;
+using net::URLRequestStatus;
+using testing::Return;
+
+namespace {
+
+class DataReductionProxyParamsMock : public DataReductionProxyParams {
+ public:
+ DataReductionProxyParamsMock() : DataReductionProxyParams(0) {}
+ virtual ~DataReductionProxyParamsMock() {}
+
+ MOCK_METHOD1(IsDataReductionProxyEligible, bool(const net::URLRequest*));
+ MOCK_CONST_METHOD2(WasDataReductionProxyUsed, bool(const net::URLRequest*,
+ std::pair<GURL, GURL>* proxy_servers));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DataReductionProxyParamsMock);
+};
+
+} // namespace
+
+namespace data_reduction_proxy {
+
+class DataReductionProxyUsageStatsTest : public testing::Test {
+ public:
+ DataReductionProxyUsageStatsTest()
+ : loop_proxy_(MessageLoopProxy::current().get()),
+ context_(true),
+ mock_url_request_(GURL(), net::IDLE, &delegate_, &context_) {
+ context_.Init();
+ }
+ // Required for MessageLoopProxy::current().
+ base::MessageLoopForUI loop_;
+ MessageLoopProxy* loop_proxy_;
+
+ protected:
+ TestURLRequestContext context_;
+ TestDelegate delegate_;
+ DataReductionProxyParamsMock mock_params_;
+ URLRequest mock_url_request_;
+};
+
+TEST_F(DataReductionProxyUsageStatsTest, isDataReductionProxyUnreachable) {
+ struct TestCase {
+ bool is_proxy_eligible;
+ bool was_proxy_used;
+ bool is_unreachable;
+ };
+ const TestCase test_cases[] = {
+ {
+ false,
+ false,
+ false
+ },
+ {
+ true,
+ true,
+ false
+ },
+ {
+ true,
+ false,
+ true
+ }
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+ TestCase test_case = test_cases[i];
+
+ EXPECT_CALL(mock_params_, IsDataReductionProxyEligible(&mock_url_request_))
+ .WillRepeatedly(Return(test_case.is_proxy_eligible));
+ EXPECT_CALL(mock_params_,
+ WasDataReductionProxyUsed(&mock_url_request_, NULL))
+ .WillRepeatedly(Return(test_case.was_proxy_used));
+
+ DataReductionProxyUsageStats* usage_stats =
+ new DataReductionProxyUsageStats(
+ &mock_params_, loop_proxy_, loop_proxy_);
+
+ usage_stats->OnUrlRequestCompleted(&mock_url_request_, false);
+ MessageLoop::current()->RunUntilIdle();
+
+ EXPECT_EQ(test_case.is_unreachable,
+ usage_stats->isDataReductionProxyUnreachable());
+ }
+}
+
+} // namespace data_reduction_proxy