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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 | 59 |
60 // TODO(mad): To be removed when we stop updating the NetworkTimeTracker. | 60 // TODO(mad): To be removed when we stop updating the NetworkTimeTracker. |
61 // For the HTTP date headers, the resolution of the server time is 1 second. | 61 // For the HTTP date headers, the resolution of the server time is 1 second. |
62 const int64 kServerTimeResolutionMs = 1000; | 62 const int64 kServerTimeResolutionMs = 1000; |
63 | 63 |
64 // Wrapper around channel checking, used to enable channel mocking for | 64 // Wrapper around channel checking, used to enable channel mocking for |
65 // testing. If the current browser channel is not UNKNOWN, this will return | 65 // testing. If the current browser channel is not UNKNOWN, this will return |
66 // that channel value. Otherwise, if the fake channel flag is provided, this | 66 // that channel value. Otherwise, if the fake channel flag is provided, this |
67 // will return the fake channel. Failing that, this will return the UNKNOWN | 67 // will return the fake channel. Failing that, this will return the UNKNOWN |
68 // channel. | 68 // channel. |
69 Study_Channel GetChannelForVariations() { | 69 variations::Study_Channel GetChannelForVariations() { |
70 switch (chrome::VersionInfo::GetChannel()) { | 70 switch (chrome::VersionInfo::GetChannel()) { |
71 case chrome::VersionInfo::CHANNEL_CANARY: | 71 case chrome::VersionInfo::CHANNEL_CANARY: |
72 return Study_Channel_CANARY; | 72 return variations::Study_Channel_CANARY; |
73 case chrome::VersionInfo::CHANNEL_DEV: | 73 case chrome::VersionInfo::CHANNEL_DEV: |
74 return Study_Channel_DEV; | 74 return variations::Study_Channel_DEV; |
75 case chrome::VersionInfo::CHANNEL_BETA: | 75 case chrome::VersionInfo::CHANNEL_BETA: |
76 return Study_Channel_BETA; | 76 return variations::Study_Channel_BETA; |
77 case chrome::VersionInfo::CHANNEL_STABLE: | 77 case chrome::VersionInfo::CHANNEL_STABLE: |
78 return Study_Channel_STABLE; | 78 return variations::Study_Channel_STABLE; |
79 case chrome::VersionInfo::CHANNEL_UNKNOWN: | 79 case chrome::VersionInfo::CHANNEL_UNKNOWN: |
80 break; | 80 break; |
81 } | 81 } |
82 const std::string forced_channel = | 82 const std::string forced_channel = |
83 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 83 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
84 switches::kFakeVariationsChannel); | 84 switches::kFakeVariationsChannel); |
85 if (forced_channel == "stable") | 85 if (forced_channel == "stable") |
86 return Study_Channel_STABLE; | 86 return variations::Study_Channel_STABLE; |
87 if (forced_channel == "beta") | 87 if (forced_channel == "beta") |
88 return Study_Channel_BETA; | 88 return variations::Study_Channel_BETA; |
89 if (forced_channel == "dev") | 89 if (forced_channel == "dev") |
90 return Study_Channel_DEV; | 90 return variations::Study_Channel_DEV; |
91 if (forced_channel == "canary") | 91 if (forced_channel == "canary") |
92 return Study_Channel_CANARY; | 92 return variations::Study_Channel_CANARY; |
93 DVLOG(1) << "Invalid channel provided: " << forced_channel; | 93 DVLOG(1) << "Invalid channel provided: " << forced_channel; |
94 return Study_Channel_UNKNOWN; | 94 return variations::Study_Channel_UNKNOWN; |
95 } | 95 } |
96 | 96 |
97 // Returns a string that will be used for the value of the 'osname' URL param | 97 // Returns a string that will be used for the value of the 'osname' URL param |
98 // to the variations server. | 98 // to the variations server. |
99 std::string GetPlatformString() { | 99 std::string GetPlatformString() { |
100 #if defined(OS_WIN) | 100 #if defined(OS_WIN) |
101 return "win"; | 101 return "win"; |
102 #elif defined(OS_IOS) | 102 #elif defined(OS_IOS) |
103 return "ios"; | 103 return "ios"; |
104 #elif defined(OS_MACOSX) | 104 #elif defined(OS_MACOSX) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 case ResourceRequestAllowedNotifier::ALLOWED: | 177 case ResourceRequestAllowedNotifier::ALLOWED: |
178 return RESOURCE_REQUESTS_ALLOWED; | 178 return RESOURCE_REQUESTS_ALLOWED; |
179 } | 179 } |
180 NOTREACHED(); | 180 NOTREACHED(); |
181 return RESOURCE_REQUESTS_NOT_ALLOWED; | 181 return RESOURCE_REQUESTS_NOT_ALLOWED; |
182 } | 182 } |
183 | 183 |
184 | 184 |
185 // Gets current form factor and converts it from enum DeviceFormFactor to enum | 185 // Gets current form factor and converts it from enum DeviceFormFactor to enum |
186 // Study_FormFactor. | 186 // Study_FormFactor. |
187 Study_FormFactor GetCurrentFormFactor() { | 187 variations::Study_FormFactor GetCurrentFormFactor() { |
188 switch (ui::GetDeviceFormFactor()) { | 188 switch (ui::GetDeviceFormFactor()) { |
189 case ui::DEVICE_FORM_FACTOR_PHONE: | 189 case ui::DEVICE_FORM_FACTOR_PHONE: |
190 return Study_FormFactor_PHONE; | 190 return variations::Study_FormFactor_PHONE; |
191 case ui::DEVICE_FORM_FACTOR_TABLET: | 191 case ui::DEVICE_FORM_FACTOR_TABLET: |
192 return Study_FormFactor_TABLET; | 192 return variations::Study_FormFactor_TABLET; |
193 case ui::DEVICE_FORM_FACTOR_DESKTOP: | 193 case ui::DEVICE_FORM_FACTOR_DESKTOP: |
194 return Study_FormFactor_DESKTOP; | 194 return variations::Study_FormFactor_DESKTOP; |
195 } | 195 } |
196 NOTREACHED(); | 196 NOTREACHED(); |
197 return Study_FormFactor_DESKTOP; | 197 return variations::Study_FormFactor_DESKTOP; |
198 } | 198 } |
199 | 199 |
200 // Gets the hardware class and returns it as a string. This returns an empty | 200 // Gets the hardware class and returns it as a string. This returns an empty |
201 // string if the client is not ChromeOS. | 201 // string if the client is not ChromeOS. |
202 std::string GetHardwareClass() { | 202 std::string GetHardwareClass() { |
203 #if defined(OS_CHROMEOS) | 203 #if defined(OS_CHROMEOS) |
204 return base::SysInfo::GetLsbReleaseBoard(); | 204 return base::SysInfo::GetLsbReleaseBoard(); |
205 #endif // OS_CHROMEOS | 205 #endif // OS_CHROMEOS |
206 return std::string(); | 206 return std::string(); |
207 } | 207 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 weak_ptr_factory_(this) { | 247 weak_ptr_factory_(this) { |
248 resource_request_allowed_notifier_->Init(this); | 248 resource_request_allowed_notifier_->Init(this); |
249 } | 249 } |
250 | 250 |
251 VariationsService::~VariationsService() { | 251 VariationsService::~VariationsService() { |
252 } | 252 } |
253 | 253 |
254 bool VariationsService::CreateTrialsFromSeed() { | 254 bool VariationsService::CreateTrialsFromSeed() { |
255 create_trials_from_seed_called_ = true; | 255 create_trials_from_seed_called_ = true; |
256 | 256 |
257 VariationsSeed seed; | 257 variations::VariationsSeed seed; |
258 if (!seed_store_.LoadSeed(&seed)) | 258 if (!seed_store_.LoadSeed(&seed)) |
259 return false; | 259 return false; |
260 | 260 |
261 const chrome::VersionInfo current_version_info; | 261 const chrome::VersionInfo current_version_info; |
262 if (!current_version_info.is_valid()) | 262 if (!current_version_info.is_valid()) |
263 return false; | 263 return false; |
264 | 264 |
265 const base::Version current_version(current_version_info.Version()); | 265 const base::Version current_version(current_version_info.Version()); |
266 if (!current_version.IsValid()) | 266 if (!current_version.IsValid()) |
267 return false; | 267 return false; |
268 | 268 |
269 VariationsSeedProcessor().CreateTrialsFromSeed( | 269 variations::VariationsSeedProcessor().CreateTrialsFromSeed( |
270 seed, | 270 seed, |
271 g_browser_process->GetApplicationLocale(), | 271 g_browser_process->GetApplicationLocale(), |
272 GetReferenceDateForExpiryChecks(local_state_), | 272 GetReferenceDateForExpiryChecks(local_state_), |
273 current_version, | 273 current_version, |
274 GetChannelForVariations(), | 274 GetChannelForVariations(), |
275 GetCurrentFormFactor(), | 275 GetCurrentFormFactor(), |
276 GetHardwareClass(), | 276 GetHardwareClass(), |
277 base::Bind(&OverrideUIString)); | 277 base::Bind(&OverrideUIString)); |
278 | 278 |
279 // Log the "freshness" of the seed that was just used. The freshness is the | 279 // Log the "freshness" of the seed that was just used. The freshness is the |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 time_since_last_fetch = now - last_request_started_time_; | 431 time_since_last_fetch = now - last_request_started_time_; |
432 UMA_HISTOGRAM_CUSTOM_COUNTS("Variations.TimeSinceLastFetchAttempt", | 432 UMA_HISTOGRAM_CUSTOM_COUNTS("Variations.TimeSinceLastFetchAttempt", |
433 time_since_last_fetch.InMinutes(), 0, | 433 time_since_last_fetch.InMinutes(), 0, |
434 base::TimeDelta::FromDays(7).InMinutes(), 50); | 434 base::TimeDelta::FromDays(7).InMinutes(), 50); |
435 last_request_started_time_ = now; | 435 last_request_started_time_ = now; |
436 } | 436 } |
437 | 437 |
438 void VariationsService::StoreSeed(const std::string& seed_data, | 438 void VariationsService::StoreSeed(const std::string& seed_data, |
439 const std::string& seed_signature, | 439 const std::string& seed_signature, |
440 const base::Time& date_fetched) { | 440 const base::Time& date_fetched) { |
441 scoped_ptr<VariationsSeed> seed(new VariationsSeed); | 441 scoped_ptr<variations::VariationsSeed> seed(new variations::VariationsSeed); |
442 if (!seed_store_.StoreSeedData(seed_data, seed_signature, date_fetched, | 442 if (!seed_store_.StoreSeedData(seed_data, seed_signature, date_fetched, |
443 seed.get())) { | 443 seed.get())) { |
444 return; | 444 return; |
445 } | 445 } |
446 RecordLastFetchTime(); | 446 RecordLastFetchTime(); |
447 | 447 |
448 // Perform seed simulation only if |state_manager_| is not-NULL. The state | 448 // Perform seed simulation only if |state_manager_| is not-NULL. The state |
449 // manager may be NULL for some unit tests. | 449 // manager may be NULL for some unit tests. |
450 if (!state_manager_) | 450 if (!state_manager_) |
451 return; | 451 return; |
(...skipping 14 matching lines...) Expand all Loading... |
466 RecordRequestsAllowedHistogram(ResourceRequestStateToHistogramValue(state)); | 466 RecordRequestsAllowedHistogram(ResourceRequestStateToHistogramValue(state)); |
467 if (state != ResourceRequestAllowedNotifier::ALLOWED) { | 467 if (state != ResourceRequestAllowedNotifier::ALLOWED) { |
468 DVLOG(1) << "Resource requests were not allowed. Waiting for notification."; | 468 DVLOG(1) << "Resource requests were not allowed. Waiting for notification."; |
469 return; | 469 return; |
470 } | 470 } |
471 | 471 |
472 DoActualFetch(); | 472 DoActualFetch(); |
473 } | 473 } |
474 | 474 |
475 void VariationsService::NotifyObservers( | 475 void VariationsService::NotifyObservers( |
476 const VariationsSeedSimulator::Result& result) { | 476 const variations::VariationsSeedSimulator::Result& result) { |
477 if (result.kill_critical_group_change_count > 0) { | 477 if (result.kill_critical_group_change_count > 0) { |
478 FOR_EACH_OBSERVER(Observer, observer_list_, | 478 FOR_EACH_OBSERVER(Observer, observer_list_, |
479 OnExperimentChangesDetected(Observer::CRITICAL)); | 479 OnExperimentChangesDetected(Observer::CRITICAL)); |
480 } else if (result.kill_best_effort_group_change_count > 0) { | 480 } else if (result.kill_best_effort_group_change_count > 0) { |
481 FOR_EACH_OBSERVER(Observer, observer_list_, | 481 FOR_EACH_OBSERVER(Observer, observer_list_, |
482 OnExperimentChangesDetected(Observer::BEST_EFFORT)); | 482 OnExperimentChangesDetected(Observer::BEST_EFFORT)); |
483 } | 483 } |
484 } | 484 } |
485 | 485 |
486 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { | 486 void VariationsService::OnURLFetchComplete(const net::URLFetcher* source) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 RecordRequestsAllowedHistogram(RESOURCE_REQUESTS_ALLOWED_NOTIFIED); | 562 RecordRequestsAllowedHistogram(RESOURCE_REQUESTS_ALLOWED_NOTIFIED); |
563 DVLOG(1) << "Retrying fetch."; | 563 DVLOG(1) << "Retrying fetch."; |
564 DoActualFetch(); | 564 DoActualFetch(); |
565 | 565 |
566 // This service must have created a scheduler in order for this to be called. | 566 // This service must have created a scheduler in order for this to be called. |
567 DCHECK(request_scheduler_.get()); | 567 DCHECK(request_scheduler_.get()); |
568 request_scheduler_->Reset(); | 568 request_scheduler_->Reset(); |
569 } | 569 } |
570 | 570 |
571 void VariationsService::PerformSimulationWithVersion( | 571 void VariationsService::PerformSimulationWithVersion( |
572 scoped_ptr<VariationsSeed> seed, | 572 scoped_ptr<variations::VariationsSeed> seed, |
573 const base::Version& version) { | 573 const base::Version& version) { |
574 if (version.IsValid()) | 574 if (version.IsValid()) |
575 return; | 575 return; |
576 | 576 |
577 const base::ElapsedTimer timer; | 577 const base::ElapsedTimer timer; |
578 | 578 |
579 scoped_ptr<const base::FieldTrial::EntropyProvider> entropy_provider = | 579 scoped_ptr<const base::FieldTrial::EntropyProvider> entropy_provider = |
580 state_manager_->CreateEntropyProvider(); | 580 state_manager_->CreateEntropyProvider(); |
581 VariationsSeedSimulator seed_simulator(*entropy_provider); | 581 variations::VariationsSeedSimulator seed_simulator(*entropy_provider); |
582 | 582 |
583 VariationsSeedSimulator::Result result = seed_simulator.SimulateSeedStudies( | 583 const variations::VariationsSeedSimulator::Result result = |
584 *seed, g_browser_process->GetApplicationLocale(), | 584 seed_simulator.SimulateSeedStudies( |
585 GetReferenceDateForExpiryChecks(local_state_), version, | 585 *seed, g_browser_process->GetApplicationLocale(), |
586 GetChannelForVariations(), GetCurrentFormFactor(), GetHardwareClass()); | 586 GetReferenceDateForExpiryChecks(local_state_), version, |
| 587 GetChannelForVariations(), GetCurrentFormFactor(), |
| 588 GetHardwareClass()); |
587 | 589 |
588 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.NormalChanges", | 590 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.NormalChanges", |
589 result.normal_group_change_count); | 591 result.normal_group_change_count); |
590 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillBestEffortChanges", | 592 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillBestEffortChanges", |
591 result.kill_best_effort_group_change_count); | 593 result.kill_best_effort_group_change_count); |
592 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillCriticalChanges", | 594 UMA_HISTOGRAM_COUNTS_100("Variations.SimulateSeed.KillCriticalChanges", |
593 result.kill_critical_group_change_count); | 595 result.kill_critical_group_change_count); |
594 | 596 |
595 UMA_HISTOGRAM_TIMES("Variations.SimulateSeed.Duration", timer.Elapsed()); | 597 UMA_HISTOGRAM_TIMES("Variations.SimulateSeed.Duration", timer.Elapsed()); |
596 | 598 |
597 NotifyObservers(result); | 599 NotifyObservers(result); |
598 } | 600 } |
599 | 601 |
600 void VariationsService::RecordLastFetchTime() { | 602 void VariationsService::RecordLastFetchTime() { |
601 // local_state_ is NULL in tests, so check it first. | 603 // local_state_ is NULL in tests, so check it first. |
602 if (local_state_) { | 604 if (local_state_) { |
603 local_state_->SetInt64(prefs::kVariationsLastFetchTime, | 605 local_state_->SetInt64(prefs::kVariationsLastFetchTime, |
604 base::Time::Now().ToInternalValue()); | 606 base::Time::Now().ToInternalValue()); |
605 } | 607 } |
606 } | 608 } |
607 | 609 |
608 } // namespace chrome_variations | 610 } // namespace chrome_variations |
OLD | NEW |