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

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

Issue 12096096: Give access to a network time kept in the variation service. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/metrics/variations/variations_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/variations_service.h" 5 #include "chrome/browser/metrics/variations/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"
(...skipping 23 matching lines...) Expand all
34 namespace { 34 namespace {
35 35
36 // Default server of Variations seed info. 36 // Default server of Variations seed info.
37 const char kDefaultVariationsServerURL[] = 37 const char kDefaultVariationsServerURL[] =
38 "https://clients4.google.com/chrome-variations/seed"; 38 "https://clients4.google.com/chrome-variations/seed";
39 const int kMaxRetrySeedFetch = 5; 39 const int kMaxRetrySeedFetch = 5;
40 40
41 // Time between seed fetches, in hours. 41 // Time between seed fetches, in hours.
42 const int kSeedFetchPeriodHours = 5; 42 const int kSeedFetchPeriodHours = 5;
43 43
44 // TODO(mad): To be moved to NetworkTimeService when available.
45 // base::TimeTicks::Now() is documented to have a resolution of
46 // ~1-15ms.
47 const int64 kTicksResolutionMs = 15;
48
49 // For the sources that are supported (HTTP date headers, TLS
50 // handshake), the resolution of the server time is 1 second.
51 const int64 kServerTimeResolutionMs = 1000;
52
44 // Maps Study_Channel enum values to corresponding chrome::VersionInfo::Channel 53 // Maps Study_Channel enum values to corresponding chrome::VersionInfo::Channel
45 // enum values. 54 // enum values.
46 chrome::VersionInfo::Channel ConvertStudyChannelToVersionChannel( 55 chrome::VersionInfo::Channel ConvertStudyChannelToVersionChannel(
47 Study_Channel study_channel) { 56 Study_Channel study_channel) {
48 switch (study_channel) { 57 switch (study_channel) {
49 case Study_Channel_CANARY: 58 case Study_Channel_CANARY:
50 return chrome::VersionInfo::CHANNEL_CANARY; 59 return chrome::VersionInfo::CHANNEL_CANARY;
51 case Study_Channel_DEV: 60 case Study_Channel_DEV:
52 return chrome::VersionInfo::CHANNEL_DEV; 61 return chrome::VersionInfo::CHANNEL_DEV;
53 case Study_Channel_BETA: 62 case Study_Channel_BETA:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 DCHECK(create_trials_from_seed_called_); 189 DCHECK(create_trials_from_seed_called_);
181 190
182 // Perform the first fetch. 191 // Perform the first fetch.
183 FetchVariationsSeed(); 192 FetchVariationsSeed();
184 193
185 // Repeat this periodically. 194 // Repeat this periodically.
186 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours), 195 timer_.Start(FROM_HERE, base::TimeDelta::FromHours(kSeedFetchPeriodHours),
187 this, &VariationsService::FetchVariationsSeed); 196 this, &VariationsService::FetchVariationsSeed);
188 } 197 }
189 198
199 bool VariationsService::GetNetworkTime(base::Time* network_time,
200 base::TimeDelta* uncertainty) const {
201 if (network_time_.is_null())
202 return false;
203 DCHECK(!network_time_ticks_.is_null());
204 DCHECK(network_time);
205 *network_time = network_time_ + (base::TimeTicks::Now() -
206 network_time_ticks_);
207 if (uncertainty)
208 *uncertainty = network_time_uncertainty_;
209 return true;
210 }
211
190 #if defined(OS_WIN) 212 #if defined(OS_WIN)
191 void VariationsService::StartGoogleUpdateRegistrySync() { 213 void VariationsService::StartGoogleUpdateRegistrySync() {
192 registry_syncer_.RequestRegistrySync(); 214 registry_syncer_.RequestRegistrySync();
193 } 215 }
194 #endif 216 #endif
195 217
196 void VariationsService::SetCreateTrialsFromSeedCalledForTesting(bool called) { 218 void VariationsService::SetCreateTrialsFromSeedCalledForTesting(bool called) {
197 create_trials_from_seed_called_ = called; 219 create_trials_from_seed_called_ = called;
198 } 220 }
199 221
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 DCHECK_EQ(pending_seed_request_.get(), source); 271 DCHECK_EQ(pending_seed_request_.get(), source);
250 // The fetcher will be deleted when the request is handled. 272 // The fetcher will be deleted when the request is handled.
251 scoped_ptr<const net::URLFetcher> request( 273 scoped_ptr<const net::URLFetcher> request(
252 pending_seed_request_.release()); 274 pending_seed_request_.release());
253 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) { 275 if (request->GetStatus().status() != net::URLRequestStatus::SUCCESS) {
254 DVLOG(1) << "Variations server request failed."; 276 DVLOG(1) << "Variations server request failed.";
255 return; 277 return;
256 } 278 }
257 279
258 // Log the response code. 280 // Log the response code.
281 int response_code = request->GetResponseCode();
Alexei Svitkine (slow) 2013/02/01 19:38:55 Nit: const
MAD 2013/02/01 22:01:41 Done.
259 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Variations.SeedFetchResponseCode", 282 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Variations.SeedFetchResponseCode",
260 net::HttpUtil::MapStatusCodeForHistogram(request->GetResponseCode()), 283 net::HttpUtil::MapStatusCodeForHistogram(response_code),
261 net::HttpUtil::GetStatusCodesForHistogram()); 284 net::HttpUtil::GetStatusCodesForHistogram());
262 285
263 const base::TimeDelta latency = 286 const base::TimeDelta latency =
264 base::TimeTicks::Now() - last_request_started_time_; 287 base::TimeTicks::Now() - last_request_started_time_;
265 288
266 if (request->GetResponseCode() != 200) { 289 base::Time response_date;
290 if (response_code == 200 || response_code == 304) {
Alexei Svitkine (slow) 2013/02/01 19:38:55 Can you change the code to use the constants from
MAD 2013/02/01 22:01:41 Done.
MAD 2013/02/01 22:01:41 Done.
291 bool success = request->GetResponseHeaders()->GetDateValue(&response_date);
292 DCHECK(success || response_date.is_null());
293
294 if (!response_date.is_null()) {
295 #ifndef NDEBUG
296 if (!network_time_.is_null()) {
297 // Check that we are tracking time correctly.
298 base::Time current_network_time;
299 base::TimeDelta uncertainty;
300 success = GetNetworkTime(&current_network_time, &uncertainty);
301 DCHECK(success);
302 // Account for response_date; s own innaccuracy.
303 uncertainty +=
304 base::TimeDelta::FromMilliseconds(kServerTimeResolutionMs) +
305 latency + 2 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs);
306 DCHECK(current_network_time >= response_date - uncertainty);
307 DCHECK(current_network_time <= response_date + uncertainty);
308 DVLOG(1) << current_network_time.ToInternalValue() << " VS "
309 << response_date.ToInternalValue() << ", is within: "
310 << uncertainty.ToInternalValue();
311 }
312 #endif // ifndef NDEBUG
313 // Update network time on every request to limit dependency on ticks lag.
314 // TODO(mad): Find a heuristic to avoid augmenting the
315 // network_time_uncertainty_ too much by a particularly long latency.
316 // Maybe only update when we either improve accuracy or drifted too far
317 // from response_date.
318 network_time_ = response_date;
319 // Estimate that the time was set midway through the latency time.
320 network_time_ticks_ = base::TimeTicks::Now() - latency / 2;
321 // We can't assume a better time than the resolution of the server time
322 // and we involve 4 ticks value, each with their own uncertainty, 1 & 2
323 // are the ones used to compute the latency, 3 is the Now() above and 4
324 // will be the Now() used in GetNetworkTime().
325 network_time_uncertainty_ =
326 base::TimeDelta::FromMilliseconds(kServerTimeResolutionMs) +
327 latency + 4 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs);
328 } // if (!response_date.is_null())
329 } else if (response_code != 200) {
267 DVLOG(1) << "Variations server request returned non-200 response code: " 330 DVLOG(1) << "Variations server request returned non-200 response code: "
268 << request->GetResponseCode(); 331 << response_code;
269 if (request->GetResponseCode() == 304) 332 if (response_code == 304)
270 UMA_HISTOGRAM_MEDIUM_TIMES("Variations.FetchNotModifiedLatency", latency); 333 UMA_HISTOGRAM_MEDIUM_TIMES("Variations.FetchNotModifiedLatency", latency);
271 else 334 else
272 UMA_HISTOGRAM_MEDIUM_TIMES("Variations.FetchOtherLatency", latency); 335 UMA_HISTOGRAM_MEDIUM_TIMES("Variations.FetchOtherLatency", latency);
273 return; 336 return;
274 } 337 }
275 UMA_HISTOGRAM_MEDIUM_TIMES("Variations.FetchSuccessLatency", latency); 338 UMA_HISTOGRAM_MEDIUM_TIMES("Variations.FetchSuccessLatency", latency);
276 339
277 std::string seed_data; 340 std::string seed_data;
278 bool success = request->GetResponseAsString(&seed_data); 341 bool success = request->GetResponseAsString(&seed_data);
279 DCHECK(success); 342 DCHECK(success);
280 343
281 base::Time response_date;
282 success = request->GetResponseHeaders()->GetDateValue(&response_date);
283 DCHECK(success || response_date.is_null());
284
285 StoreSeedData(seed_data, response_date, g_browser_process->local_state()); 344 StoreSeedData(seed_data, response_date, g_browser_process->local_state());
286 } 345 }
287 346
288 void VariationsService::OnResourceRequestsAllowed() { 347 void VariationsService::OnResourceRequestsAllowed() {
289 // Note that this only attempts to fetch the seed at most once per period 348 // Note that this only attempts to fetch the seed at most once per period
290 // (kSeedFetchPeriodHours). This works because 349 // (kSeedFetchPeriodHours). This works because
291 // |resource_request_allowed_notifier_| only calls this method if an 350 // |resource_request_allowed_notifier_| only calls this method if an
292 // attempt was made earlier that fails (which implies that the period had 351 // attempt was made earlier that fails (which implies that the period had
293 // elapsed). After a successful attempt is made, the notifier will know not 352 // elapsed). After a successful attempt is made, the notifier will know not
294 // to call this method again until another failed attempt occurs. 353 // to call this method again until another failed attempt occurs.
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 variation_id); 618 variation_id);
560 } 619 }
561 } 620 }
562 621
563 trial->SetForced(); 622 trial->SetForced();
564 if (IsStudyExpired(study, reference_date)) 623 if (IsStudyExpired(study, reference_date))
565 trial->Disable(); 624 trial->Disable();
566 } 625 }
567 626
568 } // namespace chrome_variations 627 } // namespace chrome_variations
OLDNEW
« no previous file with comments | « chrome/browser/metrics/variations/variations_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698