| 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 "base/metrics/field_trial.h" | 5 #include "base/metrics/field_trial.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 | 8 | 
| 9 #include "base/build_time.h" | 9 #include "base/build_time.h" | 
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" | 
| 11 #include "base/logging.h" | 11 #include "base/logging.h" | 
| 12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" | 
|  | 13 #include "base/strings/string_number_conversions.h" | 
| 13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" | 
| 14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" | 
| 15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" | 
| 16 | 17 | 
| 17 namespace base { | 18 namespace base { | 
| 18 | 19 | 
| 19 namespace { | 20 namespace { | 
| 20 | 21 | 
| 21 // Define a separator character to use when creating a persistent form of an | 22 // Define a separator character to use when creating a persistent form of an | 
| 22 // instance.  This is intended for use as a command line argument, passed to a | 23 // instance.  This is intended for use as a command line argument, passed to a | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 116   } | 117   } | 
| 117 } | 118 } | 
| 118 | 119 | 
| 119 // A second copy of FieldTrialList::seen_states_ that is meant to outlive the | 120 // A second copy of FieldTrialList::seen_states_ that is meant to outlive the | 
| 120 // FieldTrialList object to determine if the inconsistency happens because there | 121 // FieldTrialList object to determine if the inconsistency happens because there | 
| 121 // might be multiple FieldTrialList objects. | 122 // might be multiple FieldTrialList objects. | 
| 122 // TODO(asvitkine): Remove when crbug.com/359406 is resolved. | 123 // TODO(asvitkine): Remove when crbug.com/359406 is resolved. | 
| 123 base::LazyInstance<std::map<std::string, std::string>>::Leaky g_seen_states = | 124 base::LazyInstance<std::map<std::string, std::string>>::Leaky g_seen_states = | 
| 124     LAZY_INSTANCE_INITIALIZER; | 125     LAZY_INSTANCE_INITIALIZER; | 
| 125 | 126 | 
|  | 127 // A debug token generated during FieldTrialList construction. Used to diagnose | 
|  | 128 // crbug.com/359406. | 
|  | 129 // TODO(asvitkine): Remove when crbug.com/359406 is resolved. | 
|  | 130 int32_t g_debug_token = -1; | 
|  | 131 | 
| 126 // Tracks whether |g_seen_states| is used. Defaults to false, because unit tests | 132 // Tracks whether |g_seen_states| is used. Defaults to false, because unit tests | 
| 127 // will create multiple FieldTrialList instances. | 133 // will create multiple FieldTrialList instances. Also controls whether | 
|  | 134 // |g_debug_token| is included in the field trial state string. | 
| 128 bool g_use_global_check_states = false; | 135 bool g_use_global_check_states = false; | 
| 129 | 136 | 
| 130 }  // namespace | 137 }  // namespace | 
| 131 | 138 | 
| 132 // statics | 139 // statics | 
| 133 const int FieldTrial::kNotFinalized = -1; | 140 const int FieldTrial::kNotFinalized = -1; | 
| 134 const int FieldTrial::kDefaultGroupNumber = 0; | 141 const int FieldTrial::kDefaultGroupNumber = 0; | 
| 135 bool FieldTrial::enable_benchmarking_ = false; | 142 bool FieldTrial::enable_benchmarking_ = false; | 
| 136 | 143 | 
| 137 int FieldTrialList::kNoExpirationYear = 0; | 144 int FieldTrialList::kNoExpirationYear = 0; | 
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 255       accumulated_group_probability_(0), | 262       accumulated_group_probability_(0), | 
| 256       next_group_number_(kDefaultGroupNumber + 1), | 263       next_group_number_(kDefaultGroupNumber + 1), | 
| 257       group_(kNotFinalized), | 264       group_(kNotFinalized), | 
| 258       enable_field_trial_(true), | 265       enable_field_trial_(true), | 
| 259       forced_(false), | 266       forced_(false), | 
| 260       group_reported_(false), | 267       group_reported_(false), | 
| 261       trial_registered_(false) { | 268       trial_registered_(false) { | 
| 262   DCHECK_GT(total_probability, 0); | 269   DCHECK_GT(total_probability, 0); | 
| 263   DCHECK(!trial_name_.empty()); | 270   DCHECK(!trial_name_.empty()); | 
| 264   DCHECK(!default_group_name_.empty()); | 271   DCHECK(!default_group_name_.empty()); | 
|  | 272 | 
|  | 273   if (g_debug_token == -1) | 
|  | 274     g_debug_token = RandInt(1, INT32_MAX); | 
| 265 } | 275 } | 
| 266 | 276 | 
| 267 FieldTrial::~FieldTrial() {} | 277 FieldTrial::~FieldTrial() {} | 
| 268 | 278 | 
| 269 void FieldTrial::SetTrialRegistered() { | 279 void FieldTrial::SetTrialRegistered() { | 
| 270   DCHECK_EQ(kNotFinalized, group_); | 280   DCHECK_EQ(kNotFinalized, group_); | 
| 271   DCHECK(!trial_registered_); | 281   DCHECK(!trial_registered_); | 
| 272   trial_registered_ = true; | 282   trial_registered_ = true; | 
| 273 } | 283 } | 
| 274 | 284 | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 349   global_ = NULL; | 359   global_ = NULL; | 
| 350 } | 360 } | 
| 351 | 361 | 
| 352 // static | 362 // static | 
| 353 void FieldTrialList::EnableGlobalStateChecks() { | 363 void FieldTrialList::EnableGlobalStateChecks() { | 
| 354   CHECK(!g_use_global_check_states); | 364   CHECK(!g_use_global_check_states); | 
| 355   g_use_global_check_states = true; | 365   g_use_global_check_states = true; | 
| 356 } | 366 } | 
| 357 | 367 | 
| 358 // static | 368 // static | 
|  | 369 int32_t FieldTrialList::GetDebugToken() { | 
|  | 370   return g_debug_token; | 
|  | 371 } | 
|  | 372 | 
|  | 373 // static | 
| 359 FieldTrial* FieldTrialList::FactoryGetFieldTrial( | 374 FieldTrial* FieldTrialList::FactoryGetFieldTrial( | 
| 360     const std::string& trial_name, | 375     const std::string& trial_name, | 
| 361     FieldTrial::Probability total_probability, | 376     FieldTrial::Probability total_probability, | 
| 362     const std::string& default_group_name, | 377     const std::string& default_group_name, | 
| 363     const int year, | 378     const int year, | 
| 364     const int month, | 379     const int month, | 
| 365     const int day_of_month, | 380     const int day_of_month, | 
| 366     FieldTrial::RandomizationType randomization_type, | 381     FieldTrial::RandomizationType randomization_type, | 
| 367     int* default_group_number) { | 382     int* default_group_number) { | 
| 368   return FactoryGetFieldTrialWithRandomizationSeed( | 383   return FactoryGetFieldTrialWithRandomizationSeed( | 
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 477        it != active_groups.end(); ++it) { | 492        it != active_groups.end(); ++it) { | 
| 478     DCHECK_EQ(std::string::npos, | 493     DCHECK_EQ(std::string::npos, | 
| 479               it->trial_name.find(kPersistentStringSeparator)); | 494               it->trial_name.find(kPersistentStringSeparator)); | 
| 480     DCHECK_EQ(std::string::npos, | 495     DCHECK_EQ(std::string::npos, | 
| 481               it->group_name.find(kPersistentStringSeparator)); | 496               it->group_name.find(kPersistentStringSeparator)); | 
| 482     output->append(it->trial_name); | 497     output->append(it->trial_name); | 
| 483     output->append(1, kPersistentStringSeparator); | 498     output->append(1, kPersistentStringSeparator); | 
| 484     output->append(it->group_name); | 499     output->append(it->group_name); | 
| 485     output->append(1, kPersistentStringSeparator); | 500     output->append(1, kPersistentStringSeparator); | 
| 486   } | 501   } | 
|  | 502   if (g_use_global_check_states) { | 
|  | 503     output->append("DebugToken"); | 
|  | 504     output->append(1, kPersistentStringSeparator); | 
|  | 505     output->append(IntToString(g_debug_token)); | 
|  | 506     output->append(1, kPersistentStringSeparator); | 
|  | 507   } | 
| 487 } | 508 } | 
| 488 | 509 | 
| 489 // static | 510 // static | 
| 490 void FieldTrialList::AllStatesToString(std::string* output) { | 511 void FieldTrialList::AllStatesToString(std::string* output) { | 
| 491   if (!global_) | 512   if (!global_) | 
| 492     return; | 513     return; | 
| 493   AutoLock auto_lock(global_->lock_); | 514   AutoLock auto_lock(global_->lock_); | 
| 494 | 515 | 
| 495   for (const auto& registered : global_->registered_) { | 516   for (const auto& registered : global_->registered_) { | 
| 496     FieldTrial::State trial; | 517     FieldTrial::State trial; | 
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 686     return; | 707     return; | 
| 687   } | 708   } | 
| 688   AutoLock auto_lock(global_->lock_); | 709   AutoLock auto_lock(global_->lock_); | 
| 689   CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); | 710   CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); | 
| 690   trial->AddRef(); | 711   trial->AddRef(); | 
| 691   trial->SetTrialRegistered(); | 712   trial->SetTrialRegistered(); | 
| 692   global_->registered_[trial->trial_name()] = trial; | 713   global_->registered_[trial->trial_name()] = trial; | 
| 693 } | 714 } | 
| 694 | 715 | 
| 695 }  // namespace base | 716 }  // namespace base | 
| OLD | NEW | 
|---|