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