summaryrefslogtreecommitdiffstats
path: root/components/data_reduction_proxy
diff options
context:
space:
mode:
authorrajendrant <rajendrant@chromium.org>2016-02-19 22:35:40 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-20 06:36:56 +0000
commit85a9a607eceba2857be07bae99d16d6354d0ed58 (patch)
treefa7d9a54d0fefd25317ad708a3e13ce7dfd177aa /components/data_reduction_proxy
parentf5bf5f080c4032b233837baba60c1e03a257fd3d (diff)
downloadchromium_src-85a9a607eceba2857be07bae99d16d6354d0ed58.zip
chromium_src-85a9a607eceba2857be07bae99d16d6354d0ed58.tar.gz
chromium_src-85a9a607eceba2857be07bae99d16d6354d0ed58.tar.bz2
Data reduction proxy should not fetch configs if Chromium is in background
Config fetch failures when Chromium is in background trigger a refetch when Chromium comes to foreground. BUG=586236 Review URL: https://codereview.chromium.org/1714823003 Cr-Commit-Position: refs/heads/master@{#376636}
Diffstat (limited to 'components/data_reduction_proxy')
-rw-r--r--components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc51
-rw-r--r--components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h28
-rw-r--r--components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc107
-rw-r--r--components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc19
-rw-r--r--components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h17
5 files changed, 212 insertions, 10 deletions
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
index 96d8647e..a3bb98e 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
@@ -62,6 +62,12 @@ const char kUMAConfigServiceFetchLatency[] =
const char kUMAConfigServiceAuthExpired[] =
"DataReductionProxy.ConfigService.AuthExpired";
+#if defined(OS_ANDROID)
+// Maximum duration to wait before fetching the config, while the application
+// is in background.
+const uint32_t kMaxBackgroundFetchIntervalSeconds = 6 * 60 * 60; // 6 hours.
+#endif
+
#if defined(USE_GOOGLE_API_KEYS)
// Used in all Data Reduction Proxy URLs to specify API Key.
const char kApiKeyName[] = "key";
@@ -156,6 +162,9 @@ DataReductionProxyConfigServiceClient::DataReductionProxyConfigServiceClient(
enabled_(false),
remote_config_applied_(false),
url_request_context_getter_(nullptr),
+#if defined(OS_ANDROID)
+ foreground_fetch_pending_(false),
+#endif
previous_request_failed_authentication_(false),
failed_attempts_before_success_(0) {
DCHECK(request_options);
@@ -177,8 +186,21 @@ base::TimeDelta
DataReductionProxyConfigServiceClient::CalculateNextConfigRefreshTime(
bool fetch_succeeded,
const base::TimeDelta& config_expiration_delta,
- const base::TimeDelta& backoff_delay) const {
+ const base::TimeDelta& backoff_delay) {
DCHECK(backoff_delay >= base::TimeDelta());
+
+#if defined(OS_ANDROID)
+ foreground_fetch_pending_ = false;
+ if (!fetch_succeeded && IsApplicationStateBackground()) {
+ // If Chromium is in background, then fetch the config when Chromium comes
+ // to foreground or after max of |kMaxBackgroundFetchIntervalSeconds| and
+ // |backoff_delay|.
+ foreground_fetch_pending_ = true;
+ return std::max(backoff_delay, base::TimeDelta::FromSeconds(
+ kMaxBackgroundFetchIntervalSeconds));
+ }
+#endif
+
if (fetch_succeeded) {
return std::max(backoff_delay, config_expiration_delta);
}
@@ -189,6 +211,14 @@ DataReductionProxyConfigServiceClient::CalculateNextConfigRefreshTime(
void DataReductionProxyConfigServiceClient::InitializeOnIOThread(
net::URLRequestContextGetter* url_request_context_getter) {
DCHECK(url_request_context_getter);
+#if defined(OS_ANDROID)
+ // It is okay to use Unretained here because |app_status_listener| would be
+ // destroyed before |this|.
+ app_status_listener_.reset(
+ new base::android::ApplicationStatusListener(base::Bind(
+ &DataReductionProxyConfigServiceClient::OnApplicationStateChange,
+ base::Unretained(this))));
+#endif
net::NetworkChangeNotifier::AddIPAddressObserver(this);
url_request_context_getter_ = url_request_context_getter;
}
@@ -418,6 +448,7 @@ void DataReductionProxyConfigServiceClient::HandleResponse(
GetBackoffEntry()->InformOfRequest(succeeded);
base::TimeDelta next_config_refresh_time = CalculateNextConfigRefreshTime(
succeeded, refresh_duration, GetBackoffEntry()->GetTimeUntilRelease());
+
SetConfigRefreshTimer(next_config_refresh_time);
event_creator_->EndConfigRequest(bound_net_log_, status.error(),
response_code,
@@ -462,4 +493,22 @@ bool DataReductionProxyConfigServiceClient::ParseAndApplyProxyConfig(
return true;
}
+#if defined(OS_ANDROID)
+bool DataReductionProxyConfigServiceClient::IsApplicationStateBackground()
+ const {
+ return base::android::ApplicationStatusListener::GetState() !=
+ base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+}
+
+void DataReductionProxyConfigServiceClient::OnApplicationStateChange(
+ base::android::ApplicationState new_state) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (new_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES &&
+ foreground_fetch_pending_) {
+ foreground_fetch_pending_ = false;
+ RetrieveConfig();
+ }
+}
+#endif
+
} // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h
index 2024a26..3124c6c 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h
@@ -22,6 +22,10 @@
#include "net/url_request/url_fetcher_delegate.h"
#include "url/gurl.h"
+#if defined(OS_ANDROID)
+#include "base/android/application_status_listener.h"
+#endif // OS_ANDROID
+
namespace net {
class HostPortPair;
class HttpRequestHeaders;
@@ -110,6 +114,12 @@ class DataReductionProxyConfigServiceClient
// configuration.
void SetConfigRefreshTimer(const base::TimeDelta& delay);
+#if defined(OS_ANDROID)
+ // Returns true if Chromium is in background.
+ // Virtualized for mocking.
+ virtual bool IsApplicationStateBackground() const;
+#endif
+
private:
friend class TestDataReductionProxyConfigServiceClient;
@@ -118,7 +128,7 @@ class DataReductionProxyConfigServiceClient
base::TimeDelta CalculateNextConfigRefreshTime(
bool fetch_succeeded,
const base::TimeDelta& config_expiration,
- const base::TimeDelta& backoff_delay) const;
+ const base::TimeDelta& backoff_delay);
// Override of net::NetworkChangeNotifier::IPAddressObserver.
void OnIPAddressChanged() override;
@@ -153,6 +163,12 @@ class DataReductionProxyConfigServiceClient
// parsed and applied.
bool ParseAndApplyProxyConfig(const ClientConfig& config);
+#if defined(OS_ANDROID)
+ // Listens to when Chromium comes to foreground and fetches new client config
+ // if the config fetch is pending.
+ void OnApplicationStateChange(base::android::ApplicationState new_state);
+#endif
+
scoped_ptr<DataReductionProxyParams> params_;
// The caller must ensure that the |request_options_| outlives this instance.
@@ -203,6 +219,16 @@ class DataReductionProxyConfigServiceClient
// configuration.
base::TimeTicks config_fetch_start_time_;
+#if defined(OS_ANDROID)
+ // Listens to the application transitions from foreground to background or
+ // vice versa.
+ scoped_ptr<base::android::ApplicationStatusListener> app_status_listener_;
+
+ // True if config needs to be fetched when the application comes to
+ // foreground.
+ bool foreground_fetch_pending_;
+#endif
+
// Keeps track of whether the previous request to a Data Reduction Proxy
// failed to authenticate. This is necessary in the situation where a new
// configuration with a bad session key is obtained, but the previous request
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
index 90100fc..f67548f 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
@@ -58,7 +58,13 @@ const char kPersistedFallback[] = "persisted.net:80";
const char kPersistedSessionKey[] = "PersistedSessionKey";
// Duration (in seconds) after which the config should be refreshed.
-const int kConfingRefreshDurationSeconds = 600;
+const int kConfigRefreshDurationSeconds = 600;
+
+#if defined(OS_ANDROID)
+// Maximum duration to wait before fetching the config, while the application
+// is in background.
+const uint32_t kMaxBackgroundFetchIntervalSeconds = 6 * 60 * 60; // 6 hours.
+#endif
} // namespace
@@ -144,20 +150,20 @@ class DataReductionProxyConfigServiceClientTest : public testing::Test {
// Set up the various test ClientConfigs.
ClientConfig config =
- CreateConfig(kSuccessSessionKey, kConfingRefreshDurationSeconds, 0,
+ CreateConfig(kSuccessSessionKey, kConfigRefreshDurationSeconds, 0,
ProxyServer_ProxyScheme_HTTPS, "origin.net", 443,
ProxyServer_ProxyScheme_HTTP, "fallback.net", 80);
config.SerializeToString(&config_);
encoded_config_ = EncodeConfig(config);
ClientConfig previous_config =
- CreateConfig(kOldSuccessSessionKey, kConfingRefreshDurationSeconds, 0,
+ CreateConfig(kOldSuccessSessionKey, kConfigRefreshDurationSeconds, 0,
ProxyServer_ProxyScheme_HTTPS, "old.origin.net", 443,
ProxyServer_ProxyScheme_HTTP, "old.fallback.net", 80);
previous_config.SerializeToString(&previous_config_);
ClientConfig persisted =
- CreateConfig(kPersistedSessionKey, kConfingRefreshDurationSeconds, 0,
+ CreateConfig(kPersistedSessionKey, kConfigRefreshDurationSeconds, 0,
ProxyServer_ProxyScheme_HTTPS, "persisted.net", 443,
ProxyServer_ProxyScheme_HTTP, "persisted.net", 80);
loaded_config_ = EncodeConfig(persisted);
@@ -190,7 +196,7 @@ class DataReductionProxyConfigServiceClientTest : public testing::Test {
kSuccessOrigin, net::ProxyServer::SCHEME_HTTP));
expected_http_proxies.push_back(net::ProxyServer::FromURI(
kSuccessFallback, net::ProxyServer::SCHEME_HTTP));
- EXPECT_EQ(base::TimeDelta::FromSeconds(kConfingRefreshDurationSeconds),
+ EXPECT_EQ(base::TimeDelta::FromSeconds(kConfigRefreshDurationSeconds),
config_client()->GetDelay());
EXPECT_THAT(configurator()->proxies_for_http(),
testing::ContainerEq(expected_http_proxies));
@@ -206,7 +212,7 @@ class DataReductionProxyConfigServiceClientTest : public testing::Test {
kOldSuccessOrigin, net::ProxyServer::SCHEME_HTTP));
expected_http_proxies.push_back(net::ProxyServer::FromURI(
kOldSuccessFallback, net::ProxyServer::SCHEME_HTTP));
- EXPECT_EQ(base::TimeDelta::FromSeconds(kConfingRefreshDurationSeconds),
+ EXPECT_EQ(base::TimeDelta::FromSeconds(kConfigRefreshDurationSeconds),
config_client()->GetDelay());
EXPECT_THAT(configurator()->proxies_for_http(),
testing::ContainerEq(expected_http_proxies));
@@ -387,7 +393,7 @@ TEST_F(DataReductionProxyConfigServiceClientTest, DevRolloutAndQuic) {
config_client()->RetrieveConfig();
RunUntilIdle();
- EXPECT_EQ(base::TimeDelta::FromSeconds(kConfingRefreshDurationSeconds),
+ EXPECT_EQ(base::TimeDelta::FromSeconds(kConfigRefreshDurationSeconds),
config_client()->GetDelay())
<< i;
@@ -450,6 +456,10 @@ TEST_F(DataReductionProxyConfigServiceClientTest, EnsureBackoff) {
EXPECT_TRUE(configurator()->proxies_for_https().empty());
EXPECT_EQ(base::TimeDelta::FromSeconds(20), config_client()->GetDelay());
+#if defined(OS_ANDROID)
+ EXPECT_FALSE(config_client()->foreground_fetch_pending());
+#endif
+
// Second attempt should be unsuccessful and backoff time should increase.
config_client()->RetrieveConfig();
RunUntilIdle();
@@ -458,6 +468,10 @@ TEST_F(DataReductionProxyConfigServiceClientTest, EnsureBackoff) {
EXPECT_EQ(base::TimeDelta::FromSeconds(40), config_client()->GetDelay());
EXPECT_TRUE(persisted_config().empty());
+#if defined(OS_ANDROID)
+ EXPECT_FALSE(config_client()->foreground_fetch_pending());
+#endif
+
EXPECT_EQ(2, config_client()->failed_attempts_before_success());
histogram_tester.ExpectTotalCount(
"DataReductionProxy.ConfigService.FetchFailedAttemptsBeforeSuccess", 0);
@@ -473,6 +487,9 @@ TEST_F(DataReductionProxyConfigServiceClientTest, RemoteConfigSuccess) {
config_client()->RetrieveConfig();
RunUntilIdle();
VerifyRemoteSuccess();
+#if defined(OS_ANDROID)
+ EXPECT_FALSE(config_client()->foreground_fetch_pending());
+#endif
}
// Tests that the config is read successfully on the second attempt.
@@ -822,4 +839,80 @@ TEST_F(DataReductionProxyConfigServiceClientTest, ApplySerializedConfigLocal) {
EXPECT_FALSE(request_options()->GetSecureSession().empty());
}
+#if defined(OS_ANDROID)
+// Verifies the correctness of fetching config when Chromium is in background
+// and foreground.
+TEST_F(DataReductionProxyConfigServiceClientTest, FetchConfigOnForeground) {
+ Init(true);
+ SetDataReductionProxyEnabled(true);
+
+ {
+ // Tests that successful config fetches while Chromium is in background,
+ // does not trigger refetches when Chromium comes to foreground.
+ base::HistogramTester histogram_tester;
+ AddMockSuccess();
+ config_client()->set_application_state_background(true);
+ config_client()->RetrieveConfig();
+ RunUntilIdle();
+ VerifyRemoteSuccess();
+ EXPECT_FALSE(config_client()->foreground_fetch_pending());
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.FetchLatency", 1);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(kConfigRefreshDurationSeconds),
+ config_client()->GetDelay());
+ config_client()->set_application_state_background(false);
+ config_client()->TriggerApplicationStatusToForeground();
+ RunUntilIdle();
+ EXPECT_EQ(base::TimeDelta::FromSeconds(kConfigRefreshDurationSeconds),
+ config_client()->GetDelay());
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.FetchLatency", 1);
+ }
+
+ {
+ // Tests that config fetch failures while Chromium is in foreground does not
+ // trigger refetches when Chromium comes to foreground again.
+ base::HistogramTester histogram_tester;
+ AddMockFailure();
+ config_client()->set_application_state_background(false);
+ config_client()->RetrieveConfig();
+ RunUntilIdle();
+ EXPECT_FALSE(config_client()->foreground_fetch_pending());
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.FetchLatency", 0);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(20), config_client()->GetDelay());
+ config_client()->TriggerApplicationStatusToForeground();
+ RunUntilIdle();
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.FetchLatency", 0);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(20), config_client()->GetDelay());
+ }
+
+ {
+ // Tests that config fetch failures while Chromium is in background, trigger
+ // a refetch when Chromium comes to foreground.
+ base::HistogramTester histogram_tester;
+ AddMockFailure();
+ AddMockSuccess();
+ config_client()->set_application_state_background(true);
+ config_client()->RetrieveConfig();
+ RunUntilIdle();
+ EXPECT_TRUE(config_client()->foreground_fetch_pending());
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.FetchLatency", 0);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(kMaxBackgroundFetchIntervalSeconds),
+ config_client()->GetDelay());
+ config_client()->set_application_state_background(false);
+ config_client()->TriggerApplicationStatusToForeground();
+ RunUntilIdle();
+ EXPECT_FALSE(config_client()->foreground_fetch_pending());
+ histogram_tester.ExpectTotalCount(
+ "DataReductionProxy.ConfigService.FetchLatency", 1);
+ EXPECT_EQ(base::TimeDelta::FromSeconds(kConfigRefreshDurationSeconds),
+ config_client()->GetDelay());
+ VerifyRemoteSuccess();
+ }
+}
+#endif
+
} // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index cc72d68..d1a7a72 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -110,8 +110,12 @@ TestDataReductionProxyConfigServiceClient::
event_creator,
net_log,
config_storer),
+#if defined(OS_ANDROID)
+ is_application_state_background_(false),
+#endif
tick_clock_(base::Time::UnixEpoch()),
- test_backoff_entry_(&kTestBackoffPolicy, &tick_clock_) {}
+ test_backoff_entry_(&kTestBackoffPolicy, &tick_clock_) {
+}
TestDataReductionProxyConfigServiceClient::
~TestDataReductionProxyConfigServiceClient() {
@@ -174,6 +178,19 @@ void TestDataReductionProxyConfigServiceClient::TestTickClock::SetTime(
time_ = time;
}
+#if defined(OS_ANDROID)
+bool TestDataReductionProxyConfigServiceClient::IsApplicationStateBackground()
+ const {
+ return is_application_state_background_;
+}
+
+void TestDataReductionProxyConfigServiceClient::
+ TriggerApplicationStatusToForeground() {
+ OnApplicationStateChange(
+ base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES);
+}
+#endif
+
MockDataReductionProxyService::MockDataReductionProxyService(
DataReductionProxySettings* settings,
PrefService* prefs,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
index 1e3594b..c10d794 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
@@ -121,6 +121,19 @@ class TestDataReductionProxyConfigServiceClient
int32_t failed_attempts_before_success() const;
+#if defined(OS_ANDROID)
+ bool IsApplicationStateBackground() const override;
+
+ void set_application_state_background(bool new_state) {
+ is_application_state_background_ = new_state;
+ }
+
+ bool foreground_fetch_pending() const { return foreground_fetch_pending_; }
+
+ // Triggers the callback for Chromium status change to foreground.
+ void TriggerApplicationStatusToForeground();
+#endif
+
protected:
// Overrides of DataReductionProxyConfigServiceClient
base::Time Now() override;
@@ -145,6 +158,10 @@ class TestDataReductionProxyConfigServiceClient
base::Time time_;
};
+#if defined(OS_ANDROID)
+ bool is_application_state_background_;
+#endif
+
TestTickClock tick_clock_;
net::BackoffEntry test_backoff_entry_;
};