| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/metrics/variations_service.h" | 5 #include "chrome/browser/metrics/variations_service.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/build_time.h" | 10 #include "base/build_time.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/metrics/field_trial.h" | 13 #include "base/metrics/field_trial.h" |
| 14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "base/version.h" | 15 #include "base/version.h" |
| 16 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/metrics/proto/trials_seed.pb.h" | 17 #include "chrome/browser/metrics/proto/trials_seed.pb.h" |
| 18 #include "chrome/browser/prefs/pref_service.h" | 18 #include "chrome/browser/prefs/pref_service.h" |
| 19 #include "chrome/common/chrome_notification_types.h" |
| 19 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/common/metrics/experiments_helper.h" | 21 #include "chrome/common/metrics/experiments_helper.h" |
| 21 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
| 22 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 24 #include "content/public/browser/notification_service.h" |
| 23 #include "content/public/common/url_fetcher.h" | 25 #include "content/public/common/url_fetcher.h" |
| 24 #include "googleurl/src/gurl.h" | 26 #include "googleurl/src/gurl.h" |
| 25 #include "net/base/load_flags.h" | 27 #include "net/base/load_flags.h" |
| 26 #include "net/base/network_change_notifier.h" | 28 #include "net/base/network_change_notifier.h" |
| 27 #include "net/http/http_response_headers.h" | 29 #include "net/http/http_response_headers.h" |
| 28 #include "net/url_request/url_fetcher.h" | 30 #include "net/url_request/url_fetcher.h" |
| 29 #include "net/url_request/url_request_status.h" | 31 #include "net/url_request/url_request_status.h" |
| 30 | 32 |
| 31 namespace chrome_variations { | 33 namespace chrome_variations { |
| 32 | 34 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 server_url = kDefaultVariationsServerURL; | 94 server_url = kDefaultVariationsServerURL; |
| 93 GURL url_as_gurl = GURL(server_url); | 95 GURL url_as_gurl = GURL(server_url); |
| 94 DCHECK(url_as_gurl.is_valid()); | 96 DCHECK(url_as_gurl.is_valid()); |
| 95 return url_as_gurl; | 97 return url_as_gurl; |
| 96 } | 98 } |
| 97 | 99 |
| 98 } // namespace | 100 } // namespace |
| 99 | 101 |
| 100 VariationsService::VariationsService() | 102 VariationsService::VariationsService() |
| 101 : variations_server_url_(GetVariationsServerURL()) { | 103 : variations_server_url_(GetVariationsServerURL()) { |
| 104 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, |
| 105 content::NotificationService::AllSources()); |
| 102 } | 106 } |
| 103 | 107 |
| 104 VariationsService::~VariationsService() {} | 108 VariationsService::~VariationsService() {} |
| 105 | 109 |
| 106 bool VariationsService::CreateTrialsFromSeed(PrefService* local_prefs) { | 110 bool VariationsService::CreateTrialsFromSeed(PrefService* local_prefs) { |
| 107 TrialsSeed seed; | 111 TrialsSeed seed; |
| 108 if (!LoadTrialsSeedFromPref(local_prefs, &seed)) | 112 if (!LoadTrialsSeedFromPref(local_prefs, &seed)) |
| 109 return false; | 113 return false; |
| 110 | 114 |
| 111 const int64 date_value = local_prefs->GetInt64(prefs::kVariationsSeedDate); | 115 const int64 date_value = local_prefs->GetInt64(prefs::kVariationsSeedDate); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 137 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 134 | 138 |
| 135 // Perform the first fetch. | 139 // Perform the first fetch. |
| 136 FetchVariationsSeed(); | 140 FetchVariationsSeed(); |
| 137 | 141 |
| 138 // Repeat this periodically. | 142 // Repeat this periodically. |
| 139 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours), | 143 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours), |
| 140 this, &VariationsService::FetchVariationsSeed); | 144 this, &VariationsService::FetchVariationsSeed); |
| 141 } | 145 } |
| 142 | 146 |
| 147 // static |
| 148 void VariationsService::RegisterPrefs(PrefService* prefs) { |
| 149 prefs->RegisterStringPref(prefs::kVariationsSeed, std::string()); |
| 150 prefs->RegisterInt64Pref(prefs::kVariationsSeedDate, |
| 151 base::Time().ToInternalValue()); |
| 152 } |
| 153 |
| 143 void VariationsService::FetchVariationsSeed() { | 154 void VariationsService::FetchVariationsSeed() { |
| 144 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 155 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 145 | 156 |
| 146 const bool is_offline = net::NetworkChangeNotifier::IsOffline(); | 157 const bool is_offline = net::NetworkChangeNotifier::IsOffline(); |
| 147 UMA_HISTOGRAM_BOOLEAN("Variations.NetworkAvailability", !is_offline); | 158 UMA_HISTOGRAM_BOOLEAN("Variations.NetworkAvailability", !is_offline); |
| 148 if (is_offline) { | 159 if (is_offline) { |
| 149 DVLOG(1) << "Network was offline."; | 160 DVLOG(1) << "Network was offline."; |
| 150 return; | 161 return; |
| 151 } | 162 } |
| 152 | 163 |
| 153 pending_seed_request_.reset(net::URLFetcher::Create( | 164 pending_seed_request_.reset(net::URLFetcher::Create( |
| 154 variations_server_url_, net::URLFetcher::GET, this)); | 165 variations_server_url_, net::URLFetcher::GET, this)); |
| 155 pending_seed_request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 166 pending_seed_request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
| 156 net::LOAD_DO_NOT_SAVE_COOKIES); | 167 net::LOAD_DO_NOT_SAVE_COOKIES); |
| 157 pending_seed_request_->SetRequestContext( | 168 pending_seed_request_->SetRequestContext( |
| 158 g_browser_process->system_request_context()); | 169 g_browser_process->system_request_context()); |
| 159 pending_seed_request_->SetMaxRetries(kMaxRetrySeedFetch); | 170 pending_seed_request_->SetMaxRetries(kMaxRetrySeedFetch); |
| 160 pending_seed_request_->Start(); | 171 pending_seed_request_->Start(); |
| 161 } | 172 } |
| 162 | 173 |
| 174 void VariationsService::Observe(int type, |
| 175 const content::NotificationSource& source, |
| 176 const content::NotificationDetails& details) { |
| 177 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 178 DCHECK(type == chrome::NOTIFICATION_UPGRADE_RECOMMENDED); |
| 179 |
| 180 // An upgrade is ready, so attempt to fetch the Variations seed in case there |
| 181 // were updates. |
| 182 FetchVariationsSeed(); |
| 183 |
| 184 // Since we explicitly call FetchVariationsSeed here, we can reset the timer |
| 185 // so that we don't retry for another full period. |
| 186 if (timer_.IsRunning()) |
| 187 timer_.Reset(); |
| 188 } |
| 189 |
| 163 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { | 190 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { |
| 164 DCHECK_EQ(pending_seed_request_.get(), source); | 191 DCHECK_EQ(pending_seed_request_.get(), source); |
| 165 // When we're done handling the request, the fetcher will be deleted. | 192 // When we're done handling the request, the fetcher will be deleted. |
| 166 scoped_ptr<const net::URLFetcher> request( | 193 scoped_ptr<const net::URLFetcher> request( |
| 167 pending_seed_request_.release()); | 194 pending_seed_request_.release()); |
| 168 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) { | 195 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) { |
| 169 DVLOG(1) << "Variations server request failed."; | 196 DVLOG(1) << "Variations server request failed."; |
| 170 return; | 197 return; |
| 171 } | 198 } |
| 172 if (request->GetResponseCode() != 200) { | 199 if (request->GetResponseCode() != 200) { |
| 173 DVLOG(1) << "Variations server request returned non-200 response code: " | 200 DVLOG(1) << "Variations server request returned non-200 response code: " |
| 174 << request->GetResponseCode(); | 201 << request->GetResponseCode(); |
| 175 return; | 202 return; |
| 176 } | 203 } |
| 177 | 204 |
| 178 std::string seed_data; | 205 std::string seed_data; |
| 179 bool success = request->GetResponseAsString(&seed_data); | 206 bool success = request->GetResponseAsString(&seed_data); |
| 180 DCHECK(success); | 207 DCHECK(success); |
| 181 | 208 |
| 182 base::Time response_date; | 209 base::Time response_date; |
| 183 success = request->GetResponseHeaders()->GetDateValue(&response_date); | 210 success = request->GetResponseHeaders()->GetDateValue(&response_date); |
| 184 DCHECK(success || response_date.is_null()); | 211 DCHECK(success || response_date.is_null()); |
| 185 | 212 |
| 186 StoreSeedData(seed_data, response_date, g_browser_process->local_state()); | 213 StoreSeedData(seed_data, response_date, g_browser_process->local_state()); |
| 187 } | 214 } |
| 188 | 215 |
| 189 // static | |
| 190 void VariationsService::RegisterPrefs(PrefService* prefs) { | |
| 191 prefs->RegisterStringPref(prefs::kVariationsSeed, std::string()); | |
| 192 prefs->RegisterInt64Pref(prefs::kVariationsSeedDate, | |
| 193 base::Time().ToInternalValue()); | |
| 194 } | |
| 195 | |
| 196 bool VariationsService::StoreSeedData(const std::string& seed_data, | 216 bool VariationsService::StoreSeedData(const std::string& seed_data, |
| 197 const base::Time& seed_date, | 217 const base::Time& seed_date, |
| 198 PrefService* local_prefs) { | 218 PrefService* local_prefs) { |
| 199 // Only store the seed data if it parses correctly. | 219 // Only store the seed data if it parses correctly. |
| 200 TrialsSeed seed; | 220 TrialsSeed seed; |
| 201 if (!seed.ParseFromString(seed_data)) { | 221 if (!seed.ParseFromString(seed_data)) { |
| 202 VLOG(1) << "Variations Seed data from server is not in valid proto format, " | 222 VLOG(1) << "Variations Seed data from server is not in valid proto format, " |
| 203 << "rejecting the seed."; | 223 << "rejecting the seed."; |
| 204 return false; | 224 return false; |
| 205 } | 225 } |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 variation_id); | 470 variation_id); |
| 451 } | 471 } |
| 452 } | 472 } |
| 453 | 473 |
| 454 trial->SetForced(); | 474 trial->SetForced(); |
| 455 if (IsStudyExpired(study, reference_date)) | 475 if (IsStudyExpired(study, reference_date)) |
| 456 trial->Disable(); | 476 trial->Disable(); |
| 457 } | 477 } |
| 458 | 478 |
| 459 } // namespace chrome_variations | 479 } // namespace chrome_variations |
| OLD | NEW |