Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: chrome/browser/metrics/variations_service.cc

Issue 10790116: Have the VariationsService attempt to fetch the seed when an update is ready. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Addressed isherman's comments Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/browser/upgrade_detector.h"
20 #include "chrome/common/chrome_notification_types.h"
19 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/metrics/experiments_helper.h" 22 #include "chrome/common/metrics/experiments_helper.h"
21 #include "chrome/common/pref_names.h" 23 #include "chrome/common/pref_names.h"
22 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_service.h"
23 #include "content/public/common/url_fetcher.h" 26 #include "content/public/common/url_fetcher.h"
24 #include "googleurl/src/gurl.h" 27 #include "googleurl/src/gurl.h"
25 #include "net/base/load_flags.h" 28 #include "net/base/load_flags.h"
26 #include "net/base/network_change_notifier.h" 29 #include "net/base/network_change_notifier.h"
27 #include "net/http/http_response_headers.h" 30 #include "net/http/http_response_headers.h"
28 #include "net/url_request/url_fetcher.h" 31 #include "net/url_request/url_fetcher.h"
29 #include "net/url_request/url_request_status.h" 32 #include "net/url_request/url_request_status.h"
30 33
31 namespace chrome_variations { 34 namespace chrome_variations {
32 35
33 namespace { 36 namespace {
34 37
35 // Default server of Variations seed info. 38 // Default server of variations seed info.
36 const char kDefaultVariationsServerURL[] = 39 const char kDefaultVariationsServerURL[] =
37 "https://clients4.google.com/chrome-variations/seed"; 40 "https://clients4.google.com/chrome-variations/seed";
38 const int kMaxRetrySeedFetch = 5; 41 const int kMaxRetrySeedFetch = 5;
39 42
40 // Time between seed fetches, in hours. 43 // Time between seed fetches, in hours.
41 const int kSeedFetchPeriodHours = 5; 44 const int kSeedFetchPeriodHours = 5;
42 45
43 // Maps Study_Channel enum values to corresponding chrome::VersionInfo::Channel 46 // Maps Study_Channel enum values to corresponding chrome::VersionInfo::Channel
44 // enum values. 47 // enum values.
45 chrome::VersionInfo::Channel ConvertStudyChannelToVersionChannel( 48 chrome::VersionInfo::Channel ConvertStudyChannelToVersionChannel(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 #else 80 #else
78 #error Unknown platform 81 #error Unknown platform
79 #endif 82 #endif
80 } 83 }
81 84
82 // Converts |date_time| in Study date format to base::Time. 85 // Converts |date_time| in Study date format to base::Time.
83 base::Time ConvertStudyDateToBaseTime(int64 date_time) { 86 base::Time ConvertStudyDateToBaseTime(int64 date_time) {
84 return base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(date_time); 87 return base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(date_time);
85 } 88 }
86 89
87 // Determine and return the variations server URL. 90 // Determine and return the Variations server URL.
88 GURL GetVariationsServerURL() { 91 GURL GetVariationsServerURL() {
89 std::string server_url(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 92 std::string server_url(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
90 switches::kVariationsServerURL)); 93 switches::kVariationsServerURL));
91 if (server_url.empty()) 94 if (server_url.empty())
92 server_url = kDefaultVariationsServerURL; 95 server_url = kDefaultVariationsServerURL;
93 GURL url_as_gurl = GURL(server_url); 96 GURL url_as_gurl = GURL(server_url);
94 DCHECK(url_as_gurl.is_valid()); 97 DCHECK(url_as_gurl.is_valid());
95 return url_as_gurl; 98 return url_as_gurl;
96 } 99 }
97 100
98 } // namespace 101 } // namespace
99 102
100 VariationsService::VariationsService() 103 VariationsService::VariationsService()
101 : variations_server_url_(GetVariationsServerURL()), 104 : variations_server_url_(GetVariationsServerURL()),
102 create_trials_from_seed_called_(false) { 105 create_trials_from_seed_called_(false) {
106 registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
107 content::Source<UpgradeDetector>(UpgradeDetector::GetInstance()));
103 } 108 }
104 109
105 VariationsService::~VariationsService() {} 110 VariationsService::~VariationsService() {}
106 111
107 bool VariationsService::CreateTrialsFromSeed(PrefService* local_prefs) { 112 bool VariationsService::CreateTrialsFromSeed(PrefService* local_prefs) {
108 create_trials_from_seed_called_ = true; 113 create_trials_from_seed_called_ = true;
109 114
110 TrialsSeed seed; 115 TrialsSeed seed;
111 if (!LoadTrialsSeedFromPref(local_prefs, &seed)) 116 if (!LoadTrialsSeedFromPref(local_prefs, &seed))
112 return false; 117 return false;
(...skipping 13 matching lines...) Expand all
126 131
127 for (int i = 0; i < seed.study_size(); ++i) { 132 for (int i = 0; i < seed.study_size(); ++i) {
128 if (ShouldAddStudy(seed.study(i), current_version_info, reference_date)) 133 if (ShouldAddStudy(seed.study(i), current_version_info, reference_date))
129 CreateTrialFromStudy(seed.study(i), reference_date); 134 CreateTrialFromStudy(seed.study(i), reference_date);
130 } 135 }
131 136
132 return true; 137 return true;
133 } 138 }
134 139
135 void VariationsService::StartRepeatedVariationsSeedFetch() { 140 void VariationsService::StartRepeatedVariationsSeedFetch() {
136 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 141 DCHECK(CalledOnValidThread());
137 142
138 // Check that |CreateTrialsFromSeed| was called, which is necessary to 143 // Check that |CreateTrialsFromSeed| was called, which is necessary to
139 // retrieve the serial number that will be sent to the server. 144 // retrieve the serial number that will be sent to the server.
140 DCHECK(create_trials_from_seed_called_); 145 DCHECK(create_trials_from_seed_called_);
141 146
142 // Perform the first fetch. 147 // Perform the first fetch.
143 FetchVariationsSeed(); 148 FetchVariationsSeed();
144 149
145 // Repeat this periodically. 150 // Repeat this periodically.
146 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours), 151 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours),
147 this, &VariationsService::FetchVariationsSeed); 152 this, &VariationsService::FetchVariationsSeed);
148 } 153 }
149 154
155 // static
156 void VariationsService::RegisterPrefs(PrefService* prefs) {
157 prefs->RegisterStringPref(prefs::kVariationsSeed, std::string());
158 prefs->RegisterInt64Pref(prefs::kVariationsSeedDate,
159 base::Time().ToInternalValue());
160 }
161
150 void VariationsService::FetchVariationsSeed() { 162 void VariationsService::FetchVariationsSeed() {
151 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 163 DCHECK(CalledOnValidThread());
152 164
153 const bool is_offline = net::NetworkChangeNotifier::IsOffline(); 165 const bool is_offline = net::NetworkChangeNotifier::IsOffline();
154 UMA_HISTOGRAM_BOOLEAN("Variations.NetworkAvailability", !is_offline); 166 UMA_HISTOGRAM_BOOLEAN("Variations.NetworkAvailability", !is_offline);
155 if (is_offline) { 167 if (is_offline) {
156 DVLOG(1) << "Network was offline."; 168 DVLOG(1) << "Network was offline.";
157 return; 169 return;
158 } 170 }
159 171
160 pending_seed_request_.reset(net::URLFetcher::Create( 172 pending_seed_request_.reset(net::URLFetcher::Create(
161 variations_server_url_, net::URLFetcher::GET, this)); 173 variations_server_url_, net::URLFetcher::GET, this));
162 pending_seed_request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 174 pending_seed_request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
163 net::LOAD_DO_NOT_SAVE_COOKIES); 175 net::LOAD_DO_NOT_SAVE_COOKIES);
164 pending_seed_request_->SetRequestContext( 176 pending_seed_request_->SetRequestContext(
165 g_browser_process->system_request_context()); 177 g_browser_process->system_request_context());
166 pending_seed_request_->SetMaxRetries(kMaxRetrySeedFetch); 178 pending_seed_request_->SetMaxRetries(kMaxRetrySeedFetch);
167 if (!variations_serial_number_.empty()) { 179 if (!variations_serial_number_.empty()) {
168 pending_seed_request_->AddExtraRequestHeader("If-Match:" + 180 pending_seed_request_->AddExtraRequestHeader("If-Match:" +
169 variations_serial_number_); 181 variations_serial_number_);
170 } 182 }
171 pending_seed_request_->Start(); 183 pending_seed_request_->Start();
172 } 184 }
173 185
186 void VariationsService::Observe(int type,
187 const content::NotificationSource& source,
188 const content::NotificationDetails& details) {
189 DCHECK(CalledOnValidThread());
190 DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type);
191
192 // An upgrade is ready, so attempt to fetch the Variations seed in case there
193 // were updates.
194 FetchVariationsSeed();
195
196 // Since we explicitly call FetchVariationsSeed here, we can reset the timer
197 // so that we don't retry for another full period.
198 if (timer_.IsRunning())
199 timer_.Reset();
200 }
201
174 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { 202 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) {
175 DCHECK_EQ(pending_seed_request_.get(), source); 203 DCHECK_EQ(pending_seed_request_.get(), source);
176 // When we're done handling the request, the fetcher will be deleted. 204 // When we're done handling the request, the fetcher will be deleted.
177 scoped_ptr<const net::URLFetcher> request( 205 scoped_ptr<const net::URLFetcher> request(
178 pending_seed_request_.release()); 206 pending_seed_request_.release());
179 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) { 207 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) {
180 DVLOG(1) << "Variations server request failed."; 208 DVLOG(1) << "Variations server request failed.";
181 return; 209 return;
182 } 210 }
183 211
184 if (request->GetResponseCode() != 200) { 212 if (request->GetResponseCode() != 200) {
185 DVLOG(1) << "Variations server request returned non-200 response code: " 213 DVLOG(1) << "Variations server request returned non-200 response code: "
186 << request->GetResponseCode(); 214 << request->GetResponseCode();
187 return; 215 return;
188 } 216 }
189 217
190 std::string seed_data; 218 std::string seed_data;
191 bool success = request->GetResponseAsString(&seed_data); 219 bool success = request->GetResponseAsString(&seed_data);
192 DCHECK(success); 220 DCHECK(success);
193 221
194 base::Time response_date; 222 base::Time response_date;
195 success = request->GetResponseHeaders()->GetDateValue(&response_date); 223 success = request->GetResponseHeaders()->GetDateValue(&response_date);
196 DCHECK(success || response_date.is_null()); 224 DCHECK(success || response_date.is_null());
197 225
198 StoreSeedData(seed_data, response_date, g_browser_process->local_state()); 226 StoreSeedData(seed_data, response_date, g_browser_process->local_state());
199 } 227 }
200 228
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, 229 bool VariationsService::StoreSeedData(const std::string& seed_data,
209 const base::Time& seed_date, 230 const base::Time& seed_date,
210 PrefService* local_prefs) { 231 PrefService* local_prefs) {
211 // Only store the seed data if it parses correctly. 232 // Only store the seed data if it parses correctly.
212 TrialsSeed seed; 233 TrialsSeed seed;
213 if (!seed.ParseFromString(seed_data)) { 234 if (!seed.ParseFromString(seed_data)) {
214 VLOG(1) << "Variations Seed data from server is not in valid proto format, " 235 VLOG(1) << "Variations Seed data from server is not in valid proto format, "
215 << "rejecting the seed."; 236 << "rejecting the seed.";
216 return false; 237 return false;
217 } 238 }
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 variation_id); 485 variation_id);
465 } 486 }
466 } 487 }
467 488
468 trial->SetForced(); 489 trial->SetForced();
469 if (IsStudyExpired(study, reference_date)) 490 if (IsStudyExpired(study, reference_date))
470 trial->Disable(); 491 trial->Disable();
471 } 492 }
472 493
473 } // namespace chrome_variations 494 } // namespace chrome_variations
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698