13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/field_trial.h"
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/rand_util.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/utf_string_conversions.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace base {
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int FieldTrial::kNotFinalized = -1;
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int FieldTrial::kDefaultGroupNumber = 0;
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool FieldTrial::enable_benchmarking_ = false;
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst char FieldTrialList::kPersistentStringSeparator('/');
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kHistogramFieldTrialSeparator('_');
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FieldTrial methods and members.
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFieldTrial::FieldTrial(const std::string& name,
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       const Probability total_probability,
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       const std::string& default_group_name,
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       const int year,
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       const int month,
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       const int day_of_month)
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  : name_(name),
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    divisor_(total_probability),
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    default_group_name_(default_group_name),
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    random_(static_cast<Probability>(divisor_ * base::RandDouble())),
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    accumulated_group_probability_(0),
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    next_group_number_(kDefaultGroupNumber+1),
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    group_(kNotFinalized) {
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_GT(total_probability, 0);
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(!default_group_name_.empty());
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  FieldTrialList::Register(this);
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_GT(year, 1970);
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_GT(month, 0);
5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_LT(month, 13);
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_GT(day_of_month, 0);
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_LT(day_of_month, 32);
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Time::Exploded exploded;
5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  exploded.year = year;
5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  exploded.month = month;
57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  exploded.day_of_week = 0;  // Should be unused.
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  exploded.day_of_month = day_of_month;
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  exploded.hour = 0;
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  exploded.minute = 0;
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  exploded.second = 0;
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  exploded.millisecond = 0;
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Time expiration_time = Time::FromLocalExploded(exploded);
6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  disable_field_trial_ = (GetBuildTime() > expiration_time) ? true : false;
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint FieldTrial::AppendGroup(const std::string& name,
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            Probability group_probability) {
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(group_probability <= divisor_);
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK_GE(group_probability, 0);
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (enable_benchmarking_ || disable_field_trial_)
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    group_probability = 0;
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  accumulated_group_probability_ += group_probability;
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(accumulated_group_probability_ <= divisor_);
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (group_ == kNotFinalized && accumulated_group_probability_ > random_) {
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // This is the group that crossed the random line, so we do the assignment.
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    group_ = next_group_number_;
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (name.empty())
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base::StringAppendF(&group_name_, "%d", group_);
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      group_name_ = name;
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return next_group_number_++;
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint FieldTrial::group() {
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (group_ == kNotFinalized) {
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    accumulated_group_probability_ = divisor_;
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    group_ = kDefaultGroupNumber;
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    group_name_ = default_group_name_;
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return group_;
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstd::string FieldTrial::group_name() {
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  group();  // call group() to make group assignment was done.
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return group_name_;
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::string FieldTrial::MakeName(const std::string& name_prefix,
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 const std::string& trial_name) {
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string big_string(name_prefix);
1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  big_string.append(1, kHistogramFieldTrialSeparator);
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return big_string.append(FieldTrialList::FindFullName(trial_name));
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid FieldTrial::EnableBenchmarking() {
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK_EQ(0u, FieldTrialList::GetFieldTrialCount());
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  enable_benchmarking_ = true;
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
118731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFieldTrial::~FieldTrial() {}
119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTime FieldTrial::GetBuildTime() {
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Time integral_build_time;
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const char* kDateTime = __DATE__ " " __TIME__;
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool result = Time::FromString(ASCIIToWide(kDateTime).c_str(),
12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 &integral_build_time);
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(result);
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return integral_build_time;
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FieldTrialList methods and members.
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFieldTrialList* FieldTrialList::global_ = NULL;
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool FieldTrialList::register_without_global_ = false;
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFieldTrialList::FieldTrialList() : application_start_time_(TimeTicks::Now()) {
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!global_);
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!register_without_global_);
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  global_ = this;
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFieldTrialList::~FieldTrialList() {
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoLock auto_lock(lock_);
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (!registered_.empty()) {
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RegistrationList::iterator it = registered_.begin();
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    it->second->Release();
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    registered_.erase(it->first);
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(this == global_);
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  global_ = NULL;
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid FieldTrialList::Register(FieldTrial* trial) {
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!global_) {
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    register_without_global_ = true;
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  AutoLock auto_lock(global_->lock_);
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!global_->PreLockedFind(trial->name()));
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  trial->AddRef();
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  global_->registered_[trial->name()] = trial;
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFieldTrial* FieldTrialList::Find(const std::string& name) {
17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!global_)
17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return NULL;
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutoLock auto_lock(global_->lock_);
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return global_->PreLockedFind(name);
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint FieldTrialList::FindValue(const std::string& name) {
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  FieldTrial* field_trial = Find(name);
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (field_trial)
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return field_trial->group();
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return FieldTrial::kNotFinalized;
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::string FieldTrialList::FindFullName(const std::string& name) {
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  FieldTrial* field_trial = Find(name);
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (field_trial)
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return field_trial->group_name();
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return "";
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid FieldTrialList::StatesToString(std::string* output) {
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!global_)
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(output->empty());
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  AutoLock auto_lock(global_->lock_);
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (RegistrationList::iterator it = global_->registered_.begin();
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott       it != global_->registered_.end(); ++it) {
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const std::string name = it->first;
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    std::string group_name = it->second->group_name_internal();
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (group_name.empty())
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // No definitive winner in this trial, use default_group_name as the
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // group_name.
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      group_name = it->second->default_group_name();
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK_EQ(name.find(kPersistentStringSeparator), std::string::npos);
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    DCHECK_EQ(group_name.find(kPersistentStringSeparator), std::string::npos);
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    output->append(name);
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    output->append(1, kPersistentStringSeparator);
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    output->append(group_name);
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    output->append(1, kPersistentStringSeparator);
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool FieldTrialList::CreateTrialsInChildProcess(
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& parent_trials) {
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(global_);
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (parent_trials.empty() || !global_)
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Time::Exploded exploded;
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Time two_years_from_now =
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Time::NowFromSystemTime() + TimeDelta::FromDays(730);
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  two_years_from_now.LocalExplode(&exploded);
22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const int kTwoYearsFromNow = exploded.year;
22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t next_item = 0;
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  while (next_item < parent_trials.length()) {
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    size_t name_end = parent_trials.find(kPersistentStringSeparator, next_item);
23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (name_end == parent_trials.npos || next_item == name_end)
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    size_t group_name_end = parent_trials.find(kPersistentStringSeparator,
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                               name_end + 1);
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (group_name_end == parent_trials.npos || name_end + 1 == group_name_end)
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    std::string name(parent_trials, next_item, name_end - next_item);
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    std::string group_name(parent_trials, name_end + 1,
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                           group_name_end - name_end - 1);
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    next_item = group_name_end + 1;
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    FieldTrial *field_trial(FieldTrialList::Find(name));
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (field_trial) {
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // In single process mode, we may have already created the field trial.
24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if ((field_trial->group_name_internal() != group_name) &&
24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          (field_trial->default_group_name() != group_name))
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return false;
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      continue;
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const int kTotalProbability = 100;
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    field_trial = new FieldTrial(name, kTotalProbability, group_name,
25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 kTwoYearsFromNow, 1, 1);
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    field_trial->AppendGroup(group_name, kTotalProbability);
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
25821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
25921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsensize_t FieldTrialList::GetFieldTrialCount() {
26021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!global_)
26121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return 0;
26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  AutoLock auto_lock(global_->lock_);
26321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return global_->registered_.size();
26421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
26521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFieldTrial* FieldTrialList::PreLockedFind(const std::string& name) {
26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RegistrationList::iterator it = registered_.find(name);
26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (registered_.end() == it)
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return NULL;
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return it->second;
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}  // namespace base
274