1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/variations/child_process_field_trial_syncer.h"
6 
7 #include <set>
8 #include <utility>
9 
10 #include "base/base_switches.h"
11 #include "base/command_line.h"
12 #include "components/variations/variations_crash_keys.h"
13 
14 namespace variations {
15 
ChildProcessFieldTrialSyncer(base::FieldTrialList::Observer * observer)16 ChildProcessFieldTrialSyncer::ChildProcessFieldTrialSyncer(
17     base::FieldTrialList::Observer* observer)
18     : observer_(observer) {}
19 
~ChildProcessFieldTrialSyncer()20 ChildProcessFieldTrialSyncer::~ChildProcessFieldTrialSyncer() {}
21 
InitFieldTrialObserving(const base::CommandLine & command_line)22 void ChildProcessFieldTrialSyncer::InitFieldTrialObserving(
23     const base::CommandLine& command_line) {
24   // Set up initial set of crash dump data for field trials in this process.
25   variations::InitCrashKeys();
26 
27   // Listen for field trial activations to report them to the browser.
28   base::FieldTrialList::AddObserver(observer_);
29 
30   // Some field trials may have been activated before this point. Notify the
31   // browser of these activations now. To detect these, take the set difference
32   // of currently active trials with the initially active trials.
33   base::FieldTrial::ActiveGroups initially_active_trials;
34   base::FieldTrialList::GetInitiallyActiveFieldTrials(command_line,
35                                                       &initially_active_trials);
36   std::set<std::string> initially_active_trials_set;
37   for (const auto& entry : initially_active_trials) {
38     initially_active_trials_set.insert(std::move(entry.trial_name));
39   }
40 
41   base::FieldTrial::ActiveGroups current_active_trials;
42   base::FieldTrialList::GetActiveFieldTrialGroups(&current_active_trials);
43   for (const auto& trial : current_active_trials) {
44     if (!base::Contains(initially_active_trials_set, trial.trial_name))
45       observer_->OnFieldTrialGroupFinalized(trial.trial_name, trial.group_name);
46   }
47 }
48 
OnSetFieldTrialGroup(const std::string & trial_name,const std::string & group_name)49 void ChildProcessFieldTrialSyncer::OnSetFieldTrialGroup(
50     const std::string& trial_name,
51     const std::string& group_name) {
52   base::FieldTrial* trial =
53       base::FieldTrialList::CreateFieldTrial(trial_name, group_name);
54   // Ensure the trial is marked as "used" by calling group() on it if it is
55   // marked as activated.
56   trial->group();
57 }
58 
59 }  // namespace variations
60