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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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()), |
102 create_trials_from_seed_called_(false) { | 104 create_trials_from_seed_called_(false) { |
105 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, | |
106 content::NotificationService::AllSources()); | |
Ilya Sherman
2012/08/07 20:31:51
NotificationService::AllSources() is generally dis
SteveT
2012/08/08 18:11:39
This is an UpgradeDetector, which conveniently is
Ilya Sherman
2012/08/08 21:33:47
Lovely :)
| |
103 } | 107 } |
104 | 108 |
105 VariationsService::~VariationsService() {} | 109 VariationsService::~VariationsService() {} |
106 | 110 |
107 bool VariationsService::CreateTrialsFromSeed(PrefService* local_prefs) { | 111 bool VariationsService::CreateTrialsFromSeed(PrefService* local_prefs) { |
108 create_trials_from_seed_called_ = true; | 112 create_trials_from_seed_called_ = true; |
109 | 113 |
110 TrialsSeed seed; | 114 TrialsSeed seed; |
111 if (!LoadTrialsSeedFromPref(local_prefs, &seed)) | 115 if (!LoadTrialsSeedFromPref(local_prefs, &seed)) |
112 return false; | 116 return false; |
(...skipping 27 matching lines...) Expand all Loading... | |
140 DCHECK(create_trials_from_seed_called_); | 144 DCHECK(create_trials_from_seed_called_); |
141 | 145 |
142 // Perform the first fetch. | 146 // Perform the first fetch. |
143 FetchVariationsSeed(); | 147 FetchVariationsSeed(); |
144 | 148 |
145 // Repeat this periodically. | 149 // Repeat this periodically. |
146 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours), | 150 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours), |
147 this, &VariationsService::FetchVariationsSeed); | 151 this, &VariationsService::FetchVariationsSeed); |
148 } | 152 } |
149 | 153 |
154 // static | |
155 void VariationsService::RegisterPrefs(PrefService* prefs) { | |
156 prefs->RegisterStringPref(prefs::kVariationsSeed, std::string()); | |
157 prefs->RegisterInt64Pref(prefs::kVariationsSeedDate, | |
158 base::Time().ToInternalValue()); | |
159 } | |
160 | |
150 void VariationsService::FetchVariationsSeed() { | 161 void VariationsService::FetchVariationsSeed() { |
151 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 162 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
152 | 163 |
153 const bool is_offline = net::NetworkChangeNotifier::IsOffline(); | 164 const bool is_offline = net::NetworkChangeNotifier::IsOffline(); |
154 UMA_HISTOGRAM_BOOLEAN("Variations.NetworkAvailability", !is_offline); | 165 UMA_HISTOGRAM_BOOLEAN("Variations.NetworkAvailability", !is_offline); |
155 if (is_offline) { | 166 if (is_offline) { |
156 DVLOG(1) << "Network was offline."; | 167 DVLOG(1) << "Network was offline."; |
157 return; | 168 return; |
158 } | 169 } |
159 | 170 |
160 pending_seed_request_.reset(net::URLFetcher::Create( | 171 pending_seed_request_.reset(net::URLFetcher::Create( |
161 variations_server_url_, net::URLFetcher::GET, this)); | 172 variations_server_url_, net::URLFetcher::GET, this)); |
162 pending_seed_request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 173 pending_seed_request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
163 net::LOAD_DO_NOT_SAVE_COOKIES); | 174 net::LOAD_DO_NOT_SAVE_COOKIES); |
164 pending_seed_request_->SetRequestContext( | 175 pending_seed_request_->SetRequestContext( |
165 g_browser_process->system_request_context()); | 176 g_browser_process->system_request_context()); |
166 pending_seed_request_->SetMaxRetries(kMaxRetrySeedFetch); | 177 pending_seed_request_->SetMaxRetries(kMaxRetrySeedFetch); |
167 if (!variations_serial_number_.empty()) { | 178 if (!variations_serial_number_.empty()) { |
168 pending_seed_request_->AddExtraRequestHeader("If-Match:" + | 179 pending_seed_request_->AddExtraRequestHeader("If-Match:" + |
169 variations_serial_number_); | 180 variations_serial_number_); |
170 } | 181 } |
171 pending_seed_request_->Start(); | 182 pending_seed_request_->Start(); |
172 } | 183 } |
173 | 184 |
185 void VariationsService::Observe(int type, | |
186 const content::NotificationSource& source, | |
187 const content::NotificationDetails& details) { | |
188 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
189 DCHECK(type == chrome::NOTIFICATION_UPGRADE_RECOMMENDED); | |
Ilya Sherman
2012/08/07 20:31:51
nit: DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMM
SteveT
2012/08/08 18:11:39
Done.
| |
190 | |
191 // An upgrade is ready, so attempt to fetch the Variations seed in case there | |
Ilya Sherman
2012/08/07 20:31:51
Out of curiosity, when do we capitalize jargon lik
SteveT
2012/08/08 18:11:39
Hm, good question. I think in this file we're sort
Ilya Sherman
2012/08/08 21:33:47
Nope, was just curious. Thanks :)
| |
192 // were updates. | |
193 FetchVariationsSeed(); | |
194 | |
195 // Since we explicitly call FetchVariationsSeed here, we can reset the timer | |
196 // so that we don't retry for another full period. | |
197 if (timer_.IsRunning()) | |
198 timer_.Reset(); | |
199 } | |
200 | |
174 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { | 201 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { |
175 DCHECK_EQ(pending_seed_request_.get(), source); | 202 DCHECK_EQ(pending_seed_request_.get(), source); |
176 // When we're done handling the request, the fetcher will be deleted. | 203 // When we're done handling the request, the fetcher will be deleted. |
177 scoped_ptr<const net::URLFetcher> request( | 204 scoped_ptr<const net::URLFetcher> request( |
178 pending_seed_request_.release()); | 205 pending_seed_request_.release()); |
179 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) { | 206 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) { |
180 DVLOG(1) << "Variations server request failed."; | 207 DVLOG(1) << "Variations server request failed."; |
181 return; | 208 return; |
182 } | 209 } |
183 | 210 |
184 if (request->GetResponseCode() != 200) { | 211 if (request->GetResponseCode() != 200) { |
185 DVLOG(1) << "Variations server request returned non-200 response code: " | 212 DVLOG(1) << "Variations server request returned non-200 response code: " |
186 << request->GetResponseCode(); | 213 << request->GetResponseCode(); |
187 return; | 214 return; |
188 } | 215 } |
189 | 216 |
190 std::string seed_data; | 217 std::string seed_data; |
191 bool success = request->GetResponseAsString(&seed_data); | 218 bool success = request->GetResponseAsString(&seed_data); |
192 DCHECK(success); | 219 DCHECK(success); |
193 | 220 |
194 base::Time response_date; | 221 base::Time response_date; |
195 success = request->GetResponseHeaders()->GetDateValue(&response_date); | 222 success = request->GetResponseHeaders()->GetDateValue(&response_date); |
196 DCHECK(success || response_date.is_null()); | 223 DCHECK(success || response_date.is_null()); |
197 | 224 |
198 StoreSeedData(seed_data, response_date, g_browser_process->local_state()); | 225 StoreSeedData(seed_data, response_date, g_browser_process->local_state()); |
199 } | 226 } |
200 | 227 |
201 // static | |
202 void VariationsService::RegisterPrefs(PrefService* prefs) { | |
203 prefs->RegisterStringPref(prefs::kVariationsSeed, std::string()); | |
204 prefs->RegisterInt64Pref(prefs::kVariationsSeedDate, | |
205 base::Time().ToInternalValue()); | |
206 } | |
207 | |
208 bool VariationsService::StoreSeedData(const std::string& seed_data, | 228 bool VariationsService::StoreSeedData(const std::string& seed_data, |
209 const base::Time& seed_date, | 229 const base::Time& seed_date, |
210 PrefService* local_prefs) { | 230 PrefService* local_prefs) { |
211 // Only store the seed data if it parses correctly. | 231 // Only store the seed data if it parses correctly. |
212 TrialsSeed seed; | 232 TrialsSeed seed; |
213 if (!seed.ParseFromString(seed_data)) { | 233 if (!seed.ParseFromString(seed_data)) { |
214 VLOG(1) << "Variations Seed data from server is not in valid proto format, " | 234 VLOG(1) << "Variations Seed data from server is not in valid proto format, " |
215 << "rejecting the seed."; | 235 << "rejecting the seed."; |
216 return false; | 236 return false; |
217 } | 237 } |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 variation_id); | 484 variation_id); |
465 } | 485 } |
466 } | 486 } |
467 | 487 |
468 trial->SetForced(); | 488 trial->SetForced(); |
469 if (IsStudyExpired(study, reference_date)) | 489 if (IsStudyExpired(study, reference_date)) |
470 trial->Disable(); | 490 trial->Disable(); |
471 } | 491 } |
472 | 492 |
473 } // namespace chrome_variations | 493 } // namespace chrome_variations |
OLD | NEW |