1 // Copyright 2017 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/synthetic_trial_registry.h" 6 7 #include "base/stl_util.h" 8 9 namespace variations { 10 11 SyntheticTrialRegistry::SyntheticTrialRegistry() = default; 12 SyntheticTrialRegistry::~SyntheticTrialRegistry() = default; 13 AddSyntheticTrialObserver(SyntheticTrialObserver * observer)14void SyntheticTrialRegistry::AddSyntheticTrialObserver( 15 SyntheticTrialObserver* observer) { 16 synthetic_trial_observer_list_.AddObserver(observer); 17 if (!synthetic_trial_groups_.empty()) 18 observer->OnSyntheticTrialsChanged(synthetic_trial_groups_); 19 } 20 RemoveSyntheticTrialObserver(SyntheticTrialObserver * observer)21void SyntheticTrialRegistry::RemoveSyntheticTrialObserver( 22 SyntheticTrialObserver* observer) { 23 synthetic_trial_observer_list_.RemoveObserver(observer); 24 } 25 RegisterSyntheticFieldTrial(const SyntheticTrialGroup & trial)26void SyntheticTrialRegistry::RegisterSyntheticFieldTrial( 27 const SyntheticTrialGroup& trial) { 28 for (size_t i = 0; i < synthetic_trial_groups_.size(); ++i) { 29 if (synthetic_trial_groups_[i].id.name == trial.id.name) { 30 if (synthetic_trial_groups_[i].id.group != trial.id.group) { 31 synthetic_trial_groups_[i].id.group = trial.id.group; 32 synthetic_trial_groups_[i].start_time = base::TimeTicks::Now(); 33 NotifySyntheticTrialObservers(); 34 } 35 return; 36 } 37 } 38 39 SyntheticTrialGroup trial_group = trial; 40 trial_group.start_time = base::TimeTicks::Now(); 41 synthetic_trial_groups_.push_back(trial_group); 42 NotifySyntheticTrialObservers(); 43 } 44 RegisterSyntheticMultiGroupFieldTrial(uint32_t trial_name_hash,const std::vector<uint32_t> & group_name_hashes)45void SyntheticTrialRegistry::RegisterSyntheticMultiGroupFieldTrial( 46 uint32_t trial_name_hash, 47 const std::vector<uint32_t>& group_name_hashes) { 48 auto has_same_trial_name = [trial_name_hash](const SyntheticTrialGroup& x) { 49 return x.id.name == trial_name_hash; 50 }; 51 base::EraseIf(synthetic_trial_groups_, has_same_trial_name); 52 53 if (group_name_hashes.empty()) 54 return; 55 56 SyntheticTrialGroup trial_group(trial_name_hash, group_name_hashes[0]); 57 trial_group.start_time = base::TimeTicks::Now(); 58 for (uint32_t group_name_hash : group_name_hashes) { 59 // Note: Adding the trial group will copy it, so this re-uses the same 60 // |trial_group| struct for convenience (e.g. so start_time's all match). 61 trial_group.id.group = group_name_hash; 62 synthetic_trial_groups_.push_back(trial_group); 63 } 64 NotifySyntheticTrialObservers(); 65 } 66 NotifySyntheticTrialObservers()67void SyntheticTrialRegistry::NotifySyntheticTrialObservers() { 68 for (SyntheticTrialObserver& observer : synthetic_trial_observer_list_) { 69 observer.OnSyntheticTrialsChanged(synthetic_trial_groups_); 70 } 71 } 72 GetSyntheticFieldTrialsOlderThan(base::TimeTicks time,std::vector<ActiveGroupId> * synthetic_trials)73void SyntheticTrialRegistry::GetSyntheticFieldTrialsOlderThan( 74 base::TimeTicks time, 75 std::vector<ActiveGroupId>* synthetic_trials) { 76 DCHECK(synthetic_trials); 77 synthetic_trials->clear(); 78 for (size_t i = 0; i < synthetic_trial_groups_.size(); ++i) { 79 if (synthetic_trial_groups_[i].start_time <= time) 80 synthetic_trials->push_back(synthetic_trial_groups_[i].id); 81 } 82 } 83 84 } // namespace variations 85