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 |