| 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 |