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/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/build_time.h" | 9 #include "base/build_time.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/metrics/sparse_histogram.h" | 12 #include "base/metrics/sparse_histogram.h" |
13 #include "base/prefs/pref_registry_simple.h" | 13 #include "base/prefs/pref_registry_simple.h" |
14 #include "base/prefs/pref_service.h" | 14 #include "base/prefs/pref_service.h" |
15 #include "base/sys_info.h" | 15 #include "base/sys_info.h" |
| 16 #include "base/task_runner_util.h" |
16 #include "base/timer/elapsed_timer.h" | 17 #include "base/timer/elapsed_timer.h" |
17 #include "base/version.h" | 18 #include "base/version.h" |
18 #include "chrome/browser/browser_process.h" | 19 #include "chrome/browser/browser_process.h" |
19 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
20 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
21 #include "components/metrics/metrics_state_manager.h" | 22 #include "components/metrics/metrics_state_manager.h" |
22 #include "components/network_time/network_time_tracker.h" | 23 #include "components/network_time/network_time_tracker.h" |
23 #include "components/pref_registry/pref_registry_syncable.h" | 24 #include "components/pref_registry/pref_registry_syncable.h" |
24 #include "components/variations/proto/variations_seed.pb.h" | 25 #include "components/variations/proto/variations_seed.pb.h" |
25 #include "components/variations/variations_seed_processor.h" | 26 #include "components/variations/variations_seed_processor.h" |
26 #include "components/variations/variations_seed_simulator.h" | 27 #include "components/variations/variations_seed_simulator.h" |
27 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
28 #include "net/base/load_flags.h" | 29 #include "net/base/load_flags.h" |
29 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
30 #include "net/base/network_change_notifier.h" | 31 #include "net/base/network_change_notifier.h" |
31 #include "net/base/url_util.h" | 32 #include "net/base/url_util.h" |
32 #include "net/http/http_response_headers.h" | 33 #include "net/http/http_response_headers.h" |
33 #include "net/http/http_status_code.h" | 34 #include "net/http/http_status_code.h" |
34 #include "net/http/http_util.h" | 35 #include "net/http/http_util.h" |
35 #include "net/url_request/url_fetcher.h" | 36 #include "net/url_request/url_fetcher.h" |
36 #include "net/url_request/url_request_status.h" | 37 #include "net/url_request/url_request_status.h" |
37 #include "ui/base/device_form_factor.h" | 38 #include "ui/base/device_form_factor.h" |
38 #include "url/gurl.h" | 39 #include "url/gurl.h" |
39 | 40 |
| 41 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) |
| 42 #include "chrome/browser/upgrade_detector_impl.h" |
| 43 #endif |
| 44 |
40 #if defined(OS_CHROMEOS) | 45 #if defined(OS_CHROMEOS) |
41 #include "chrome/browser/chromeos/settings/cros_settings.h" | 46 #include "chrome/browser/chromeos/settings/cros_settings.h" |
42 #endif | 47 #endif |
43 | 48 |
44 namespace chrome_variations { | 49 namespace chrome_variations { |
45 | 50 |
46 namespace { | 51 namespace { |
47 | 52 |
48 // Default server of Variations seed info. | 53 // Default server of Variations seed info. |
49 const char kDefaultVariationsServerURL[] = | 54 const char kDefaultVariationsServerURL[] = |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 return "android"; | 107 return "android"; |
103 #elif defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS) | 108 #elif defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS) |
104 // Default BSD and SOLARIS to Linux to not break those builds, although these | 109 // Default BSD and SOLARIS to Linux to not break those builds, although these |
105 // platforms are not officially supported by Chrome. | 110 // platforms are not officially supported by Chrome. |
106 return "linux"; | 111 return "linux"; |
107 #else | 112 #else |
108 #error Unknown platform | 113 #error Unknown platform |
109 #endif | 114 #endif |
110 } | 115 } |
111 | 116 |
| 117 // Gets the version number to use for variations seed simulation. Must be called |
| 118 // on a thread where IO is allowed. |
| 119 base::Version GetVersionForSimulation() { |
| 120 #if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) |
| 121 const base::Version installed_version = |
| 122 UpgradeDetectorImpl::GetCurrentlyInstalledVersion(); |
| 123 if (installed_version.IsValid()) |
| 124 return installed_version; |
| 125 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS) |
| 126 |
| 127 // TODO(asvitkine): Get the version that will be used on restart instead of |
| 128 // the current version on Android, iOS and ChromeOS. |
| 129 return base::Version(chrome::VersionInfo().Version()); |
| 130 } |
| 131 |
112 // Gets the restrict parameter from |policy_pref_service| or from Chrome OS | 132 // Gets the restrict parameter from |policy_pref_service| or from Chrome OS |
113 // settings in the case of that platform. | 133 // settings in the case of that platform. |
114 std::string GetRestrictParameterPref(PrefService* policy_pref_service) { | 134 std::string GetRestrictParameterPref(PrefService* policy_pref_service) { |
115 std::string parameter; | 135 std::string parameter; |
116 #if defined(OS_CHROMEOS) | 136 #if defined(OS_CHROMEOS) |
117 chromeos::CrosSettings::Get()->GetString( | 137 chromeos::CrosSettings::Get()->GetString( |
118 chromeos::kVariationsRestrictParameter, ¶meter); | 138 chromeos::kVariationsRestrictParameter, ¶meter); |
119 #else | 139 #else |
120 if (policy_pref_service) { | 140 if (policy_pref_service) { |
121 parameter = | 141 parameter = |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 | 222 |
203 VariationsService::VariationsService( | 223 VariationsService::VariationsService( |
204 PrefService* local_state, | 224 PrefService* local_state, |
205 metrics::MetricsStateManager* state_manager) | 225 metrics::MetricsStateManager* state_manager) |
206 : local_state_(local_state), | 226 : local_state_(local_state), |
207 state_manager_(state_manager), | 227 state_manager_(state_manager), |
208 policy_pref_service_(local_state), | 228 policy_pref_service_(local_state), |
209 seed_store_(local_state), | 229 seed_store_(local_state), |
210 create_trials_from_seed_called_(false), | 230 create_trials_from_seed_called_(false), |
211 initial_request_completed_(false), | 231 initial_request_completed_(false), |
212 resource_request_allowed_notifier_( | 232 resource_request_allowed_notifier_(new ResourceRequestAllowedNotifier), |
213 new ResourceRequestAllowedNotifier) { | 233 weak_ptr_factory_(this) { |
214 resource_request_allowed_notifier_->Init(this); | 234 resource_request_allowed_notifier_->Init(this); |
215 } | 235 } |
216 | 236 |
217 VariationsService::VariationsService( | 237 VariationsService::VariationsService( |
218 ResourceRequestAllowedNotifier* notifier, | 238 ResourceRequestAllowedNotifier* notifier, |
219 PrefService* local_state, | 239 PrefService* local_state, |
220 metrics::MetricsStateManager* state_manager) | 240 metrics::MetricsStateManager* state_manager) |
221 : local_state_(local_state), | 241 : local_state_(local_state), |
222 state_manager_(state_manager), | 242 state_manager_(state_manager), |
223 policy_pref_service_(local_state), | 243 policy_pref_service_(local_state), |
224 seed_store_(local_state), | 244 seed_store_(local_state), |
225 create_trials_from_seed_called_(false), | 245 create_trials_from_seed_called_(false), |
226 initial_request_completed_(false), | 246 initial_request_completed_(false), |
227 resource_request_allowed_notifier_(notifier) { | 247 resource_request_allowed_notifier_(notifier), |
| 248 weak_ptr_factory_(this) { |
228 resource_request_allowed_notifier_->Init(this); | 249 resource_request_allowed_notifier_->Init(this); |
229 } | 250 } |
230 | 251 |
231 VariationsService::~VariationsService() { | 252 VariationsService::~VariationsService() { |
232 } | 253 } |
233 | 254 |
234 bool VariationsService::CreateTrialsFromSeed() { | 255 bool VariationsService::CreateTrialsFromSeed() { |
235 create_trials_from_seed_called_ = true; | 256 create_trials_from_seed_called_ = true; |
236 | 257 |
237 VariationsSeed seed; | 258 VariationsSeed seed; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 time_since_last_fetch = now - last_request_started_time_; | 418 time_since_last_fetch = now - last_request_started_time_; |
398 UMA_HISTOGRAM_CUSTOM_COUNTS("Variations.TimeSinceLastFetchAttempt", | 419 UMA_HISTOGRAM_CUSTOM_COUNTS("Variations.TimeSinceLastFetchAttempt", |
399 time_since_last_fetch.InMinutes(), 0, | 420 time_since_last_fetch.InMinutes(), 0, |
400 base::TimeDelta::FromDays(7).InMinutes(), 50); | 421 base::TimeDelta::FromDays(7).InMinutes(), 50); |
401 last_request_started_time_ = now; | 422 last_request_started_time_ = now; |
402 } | 423 } |
403 | 424 |
404 void VariationsService::StoreSeed(const std::string& seed_data, | 425 void VariationsService::StoreSeed(const std::string& seed_data, |
405 const std::string& seed_signature, | 426 const std::string& seed_signature, |
406 const base::Time& date_fetched) { | 427 const base::Time& date_fetched) { |
407 VariationsSeed seed; | 428 scoped_ptr<VariationsSeed> seed(new VariationsSeed); |
408 if (!seed_store_.StoreSeedData(seed_data, seed_signature, date_fetched, | 429 if (!seed_store_.StoreSeedData(seed_data, seed_signature, date_fetched, |
409 &seed)) { | 430 seed.get())) { |
410 return; | 431 return; |
411 } | 432 } |
412 RecordLastFetchTime(); | 433 RecordLastFetchTime(); |
413 | 434 |
414 // Perform seed simulation only if |state_manager_| is not-NULL. The state | 435 // Perform seed simulation only if |state_manager_| is not-NULL. The state |
415 // manager may be NULL for some unit tests. | 436 // manager may be NULL for some unit tests. |
416 if (!state_manager_) | 437 if (!state_manager_) |
417 return; | 438 return; |
418 | 439 |
419 const base::ElapsedTimer timer; | 440 base::PostTaskAndReplyWithResult( |
420 | 441 content::BrowserThread::GetBlockingPool(), |
421 // TODO(asvitkine): Get the version that will be used on restart instead of | 442 FROM_HERE, |
422 // the current version (i.e. if an update has been downloaded). | 443 base::Bind(&GetVersionForSimulation), |
423 const chrome::VersionInfo current_version_info; | 444 base::Bind(&VariationsService::PerformSimulationWithVersion, |
424 if (!current_version_info.is_valid()) | 445 weak_ptr_factory_.GetWeakPtr(), base::Passed(&seed))); |
425 return; | |
426 | |
427 const base::Version current_version(current_version_info.Version()); | |
428 if (!current_version.IsValid()) | |
429 return; | |
430 | |
431 scoped_ptr<const base::FieldTrial::EntropyProvider> entropy_provider = | |
432 state_manager_->CreateEntropyProvider(); | |
433 VariationsSeedSimulator seed_simulator(*entropy_provider); | |
434 | |
435 VariationsSeedSimulator::Result result = seed_simulator.SimulateSeedStudies( | |
436 seed, g_browser_process->GetApplicationLocale(), | |
437 GetReferenceDateForExpiryChecks(local_state_), current_version, | |
438 GetChannelForVariations(), GetCurrentFormFactor(), GetHardwareClass()); | |
439 | |
440 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.NormalChanges", | |
441 result.normal_group_change_count); | |
442 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillBestEffortChanges", | |
443 result.kill_best_effort_group_change_count); | |
444 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillCriticalChanges", | |
445 result.kill_critical_group_change_count); | |
446 | |
447 UMA_HISTOGRAM_TIMES("Variations.SimulateSeed.Duration", timer.Elapsed()); | |
448 } | 446 } |
449 | 447 |
450 void VariationsService::FetchVariationsSeed() { | 448 void VariationsService::FetchVariationsSeed() { |
451 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 449 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
452 | 450 |
453 const ResourceRequestAllowedNotifier::State state = | 451 const ResourceRequestAllowedNotifier::State state = |
454 resource_request_allowed_notifier_->GetResourceRequestsAllowedState(); | 452 resource_request_allowed_notifier_->GetResourceRequestsAllowedState(); |
455 RecordRequestsAllowedHistogram(ResourceRequestStateToHistogramValue(state)); | 453 RecordRequestsAllowedHistogram(ResourceRequestStateToHistogramValue(state)); |
456 if (state != ResourceRequestAllowedNotifier::ALLOWED) { | 454 if (state != ResourceRequestAllowedNotifier::ALLOWED) { |
457 DVLOG(1) << "Resource requests were not allowed. Waiting for notification."; | 455 DVLOG(1) << "Resource requests were not allowed. Waiting for notification."; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 // to call this method again until another failed attempt occurs. | 537 // to call this method again until another failed attempt occurs. |
540 RecordRequestsAllowedHistogram(RESOURCE_REQUESTS_ALLOWED_NOTIFIED); | 538 RecordRequestsAllowedHistogram(RESOURCE_REQUESTS_ALLOWED_NOTIFIED); |
541 DVLOG(1) << "Retrying fetch."; | 539 DVLOG(1) << "Retrying fetch."; |
542 DoActualFetch(); | 540 DoActualFetch(); |
543 | 541 |
544 // This service must have created a scheduler in order for this to be called. | 542 // This service must have created a scheduler in order for this to be called. |
545 DCHECK(request_scheduler_.get()); | 543 DCHECK(request_scheduler_.get()); |
546 request_scheduler_->Reset(); | 544 request_scheduler_->Reset(); |
547 } | 545 } |
548 | 546 |
| 547 void VariationsService::PerformSimulationWithVersion( |
| 548 scoped_ptr<VariationsSeed> seed, |
| 549 const base::Version& version) { |
| 550 if (version.IsValid()) |
| 551 return; |
| 552 |
| 553 const base::ElapsedTimer timer; |
| 554 |
| 555 scoped_ptr<const base::FieldTrial::EntropyProvider> entropy_provider = |
| 556 state_manager_->CreateEntropyProvider(); |
| 557 VariationsSeedSimulator seed_simulator(*entropy_provider); |
| 558 |
| 559 VariationsSeedSimulator::Result result = seed_simulator.SimulateSeedStudies( |
| 560 *seed, g_browser_process->GetApplicationLocale(), |
| 561 GetReferenceDateForExpiryChecks(local_state_), version, |
| 562 GetChannelForVariations(), GetCurrentFormFactor(), GetHardwareClass()); |
| 563 |
| 564 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.NormalChanges", |
| 565 result.normal_group_change_count); |
| 566 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillBestEffortChanges", |
| 567 result.kill_best_effort_group_change_count); |
| 568 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillCriticalChanges", |
| 569 result.kill_critical_group_change_count); |
| 570 |
| 571 UMA_HISTOGRAM_TIMES("Variations.SimulateSeed.Duration", timer.Elapsed()); |
| 572 } |
| 573 |
549 void VariationsService::RecordLastFetchTime() { | 574 void VariationsService::RecordLastFetchTime() { |
550 // local_state_ is NULL in tests, so check it first. | 575 // local_state_ is NULL in tests, so check it first. |
551 if (local_state_) { | 576 if (local_state_) { |
552 local_state_->SetInt64(prefs::kVariationsLastFetchTime, | 577 local_state_->SetInt64(prefs::kVariationsLastFetchTime, |
553 base::Time::Now().ToInternalValue()); | 578 base::Time::Now().ToInternalValue()); |
554 } | 579 } |
555 } | 580 } |
556 | 581 |
557 } // namespace chrome_variations | 582 } // namespace chrome_variations |
OLD | NEW |