Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(618)

Side by Side Diff: base/metrics/field_trial_params.cc

Issue 2667553002: Move API for field trial params to base from variations. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/metrics/field_trial_params.h ('k') | base/metrics/field_trial_params_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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 "components/variations/variations_associated_data.h" 5 #include "base/metrics/field_trial_params.h"
6
7 #include <map>
8 #include <utility>
9 #include <vector>
10 6
11 #include "base/feature_list.h" 7 #include "base/feature_list.h"
12 #include "base/macros.h"
13 #include "base/memory/singleton.h"
14 #include "base/metrics/field_trial.h" 8 #include "base/metrics/field_trial.h"
15 #include "base/metrics/field_trial_param_associator.h" 9 #include "base/metrics/field_trial_param_associator.h"
16 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h"
18 #include "components/variations/variations_http_header_provider.h"
19 11
20 namespace variations { 12 namespace base {
21 13
22 namespace { 14 bool AssociateFieldTrialParams(
23
24 // The internal singleton accessor for the map, used to keep it thread-safe.
25 class GroupMapAccessor {
26 public:
27 typedef std::map<ActiveGroupId, VariationID, ActiveGroupIdCompare>
28 GroupToIDMap;
29
30 // Retrieve the singleton.
31 static GroupMapAccessor* GetInstance() {
32 return base::Singleton<GroupMapAccessor>::get();
33 }
34
35 // Note that this normally only sets the ID for a group the first time, unless
36 // |force| is set to true, in which case it will always override it.
37 void AssociateID(IDCollectionKey key,
38 const ActiveGroupId& group_identifier,
39 const VariationID id,
40 const bool force) {
41 #if !defined(NDEBUG)
42 DCHECK_EQ(4, ID_COLLECTION_COUNT);
43 // Ensure that at most one of the trigger/non-trigger/signed-in web property
44 // IDs are set.
45 if (key == GOOGLE_WEB_PROPERTIES || key == GOOGLE_WEB_PROPERTIES_TRIGGER ||
46 key == GOOGLE_WEB_PROPERTIES_SIGNED_IN) {
47 if (key != GOOGLE_WEB_PROPERTIES)
48 DCHECK_EQ(EMPTY_ID, GetID(GOOGLE_WEB_PROPERTIES, group_identifier));
49 if (key != GOOGLE_WEB_PROPERTIES_TRIGGER) {
50 DCHECK_EQ(EMPTY_ID,
51 GetID(GOOGLE_WEB_PROPERTIES_TRIGGER, group_identifier));
52 }
53 if (key != GOOGLE_WEB_PROPERTIES_SIGNED_IN) {
54 DCHECK_EQ(EMPTY_ID,
55 GetID(GOOGLE_WEB_PROPERTIES_SIGNED_IN, group_identifier));
56 }
57 }
58
59 // Validate that all collections with this |group_identifier| have the same
60 // associated ID.
61 for (int i = 0; i < ID_COLLECTION_COUNT; ++i) {
62 IDCollectionKey other_key = static_cast<IDCollectionKey>(i);
63 if (other_key == key)
64 continue;
65 VariationID other_id = GetID(other_key, group_identifier);
66 DCHECK(other_id == EMPTY_ID || other_id == id);
67 }
68 #endif
69
70 base::AutoLock scoped_lock(lock_);
71
72 GroupToIDMap* group_to_id_map = GetGroupToIDMap(key);
73 if (force ||
74 group_to_id_map->find(group_identifier) == group_to_id_map->end())
75 (*group_to_id_map)[group_identifier] = id;
76 }
77
78 VariationID GetID(IDCollectionKey key,
79 const ActiveGroupId& group_identifier) {
80 base::AutoLock scoped_lock(lock_);
81 GroupToIDMap* group_to_id_map = GetGroupToIDMap(key);
82 GroupToIDMap::const_iterator it = group_to_id_map->find(group_identifier);
83 if (it == group_to_id_map->end())
84 return EMPTY_ID;
85 return it->second;
86 }
87
88 void ClearAllMapsForTesting() {
89 base::AutoLock scoped_lock(lock_);
90
91 for (int i = 0; i < ID_COLLECTION_COUNT; ++i) {
92 GroupToIDMap* map = GetGroupToIDMap(static_cast<IDCollectionKey>(i));
93 DCHECK(map);
94 map->clear();
95 }
96 }
97
98 private:
99 friend struct base::DefaultSingletonTraits<GroupMapAccessor>;
100
101 // Retrieves the GroupToIDMap for |key|.
102 GroupToIDMap* GetGroupToIDMap(IDCollectionKey key) {
103 return &group_to_id_maps_[key];
104 }
105
106 GroupMapAccessor() {
107 group_to_id_maps_.resize(ID_COLLECTION_COUNT);
108 }
109 ~GroupMapAccessor() {}
110
111 base::Lock lock_;
112 std::vector<GroupToIDMap> group_to_id_maps_;
113
114 DISALLOW_COPY_AND_ASSIGN(GroupMapAccessor);
115 };
116 } // namespace
117
118 void AssociateGoogleVariationID(IDCollectionKey key,
119 const std::string& trial_name,
120 const std::string& group_name,
121 VariationID id) {
122 GroupMapAccessor::GetInstance()->AssociateID(
123 key, MakeActiveGroupId(trial_name, group_name), id, false);
124 }
125
126 void AssociateGoogleVariationIDForce(IDCollectionKey key,
127 const std::string& trial_name,
128 const std::string& group_name,
129 VariationID id) {
130 AssociateGoogleVariationIDForceHashes(
131 key, MakeActiveGroupId(trial_name, group_name), id);
132 }
133
134 void AssociateGoogleVariationIDForceHashes(IDCollectionKey key,
135 const ActiveGroupId& active_group,
136 VariationID id) {
137 GroupMapAccessor::GetInstance()->AssociateID(key, active_group, id, true);
138 }
139
140 VariationID GetGoogleVariationID(IDCollectionKey key,
141 const std::string& trial_name,
142 const std::string& group_name) {
143 return GetGoogleVariationIDFromHashes(
144 key, MakeActiveGroupId(trial_name, group_name));
145 }
146
147 VariationID GetGoogleVariationIDFromHashes(
148 IDCollectionKey key,
149 const ActiveGroupId& active_group) {
150 return GroupMapAccessor::GetInstance()->GetID(key, active_group);
151 }
152
153 bool AssociateVariationParams(
154 const std::string& trial_name, 15 const std::string& trial_name,
155 const std::string& group_name, 16 const std::string& group_name,
156 const std::map<std::string, std::string>& params) { 17 const std::map<std::string, std::string>& params) {
157 return base::FieldTrialParamAssociator::GetInstance() 18 return base::FieldTrialParamAssociator::GetInstance()
158 ->AssociateFieldTrialParams(trial_name, group_name, params); 19 ->AssociateFieldTrialParams(trial_name, group_name, params);
159 } 20 }
160 21
161 bool GetVariationParams(const std::string& trial_name, 22 bool GetFieldTrialParams(const std::string& trial_name,
162 std::map<std::string, std::string>* params) { 23 std::map<std::string, std::string>* params) {
163 return base::FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams( 24 return base::FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams(
164 trial_name, params); 25 trial_name, params);
165 } 26 }
166 27
167 bool GetVariationParamsByFeature(const base::Feature& feature, 28 bool GetFieldTrialParamsByFeature(const base::Feature& feature,
168 std::map<std::string, std::string>* params) { 29 std::map<std::string, std::string>* params) {
169 if (!base::FeatureList::IsEnabled(feature)) 30 if (!base::FeatureList::IsEnabled(feature))
170 return false; 31 return false;
171 32
172 base::FieldTrial* trial = base::FeatureList::GetFieldTrial(feature); 33 base::FieldTrial* trial = base::FeatureList::GetFieldTrial(feature);
173 if (!trial) 34 if (!trial)
174 return false; 35 return false;
175 36
176 return GetVariationParams(trial->trial_name(), params); 37 return GetFieldTrialParams(trial->trial_name(), params);
177 } 38 }
178 39
179 std::string GetVariationParamValue(const std::string& trial_name, 40 std::string GetFieldTrialParamValue(const std::string& trial_name,
180 const std::string& param_name) { 41 const std::string& param_name) {
181 std::map<std::string, std::string> params; 42 std::map<std::string, std::string> params;
182 if (GetVariationParams(trial_name, &params)) { 43 if (GetFieldTrialParams(trial_name, &params)) {
183 std::map<std::string, std::string>::iterator it = params.find(param_name); 44 std::map<std::string, std::string>::iterator it = params.find(param_name);
184 if (it != params.end()) 45 if (it != params.end())
185 return it->second; 46 return it->second;
186 } 47 }
187 return std::string(); 48 return std::string();
188 } 49 }
189 50
190 std::string GetVariationParamValueByFeature(const base::Feature& feature, 51 std::string GetFieldTrialParamValueByFeature(const base::Feature& feature,
191 const std::string& param_name) { 52 const std::string& param_name) {
192 if (!base::FeatureList::IsEnabled(feature)) 53 if (!base::FeatureList::IsEnabled(feature))
193 return std::string(); 54 return std::string();
194 55
195 base::FieldTrial* trial = base::FeatureList::GetFieldTrial(feature); 56 base::FieldTrial* trial = base::FeatureList::GetFieldTrial(feature);
196 if (!trial) 57 if (!trial)
197 return std::string(); 58 return std::string();
198 59
199 return GetVariationParamValue(trial->trial_name(), param_name); 60 return GetFieldTrialParamValue(trial->trial_name(), param_name);
200 } 61 }
201 62
202 int GetVariationParamByFeatureAsInt(const base::Feature& feature, 63 int GetFieldTrialParamByFeatureAsInt(const base::Feature& feature,
203 const std::string& param_name, 64 const std::string& param_name,
204 int default_value) { 65 int default_value) {
205 std::string value_as_string = 66 std::string value_as_string =
206 GetVariationParamValueByFeature(feature, param_name); 67 GetFieldTrialParamValueByFeature(feature, param_name);
207 int value_as_int = 0; 68 int value_as_int = 0;
208 if (!base::StringToInt(value_as_string, &value_as_int)) { 69 if (!base::StringToInt(value_as_string, &value_as_int)) {
209 if (!value_as_string.empty()) { 70 if (!value_as_string.empty()) {
210 DLOG(WARNING) << "Failed to parse variation param " << param_name 71 DLOG(WARNING) << "Failed to parse field trial param " << param_name
211 << " with string value " << value_as_string 72 << " with string value " << value_as_string
212 << " under feature " << feature.name 73 << " under feature " << feature.name
213 << " into an int. Falling back to default value of " 74 << " into an int. Falling back to default value of "
214 << default_value; 75 << default_value;
215 } 76 }
216 value_as_int = default_value; 77 value_as_int = default_value;
217 } 78 }
218 return value_as_int; 79 return value_as_int;
219 } 80 }
220 81
221 double GetVariationParamByFeatureAsDouble(const base::Feature& feature, 82 double GetFieldTrialParamByFeatureAsDouble(const base::Feature& feature,
222 const std::string& param_name, 83 const std::string& param_name,
223 double default_value) { 84 double default_value) {
224 std::string value_as_string = 85 std::string value_as_string =
225 GetVariationParamValueByFeature(feature, param_name); 86 GetFieldTrialParamValueByFeature(feature, param_name);
226 double value_as_double = 0; 87 double value_as_double = 0;
227 if (!base::StringToDouble(value_as_string, &value_as_double)) { 88 if (!base::StringToDouble(value_as_string, &value_as_double)) {
228 if (!value_as_string.empty()) { 89 if (!value_as_string.empty()) {
229 DLOG(WARNING) << "Failed to parse variation param " << param_name 90 DLOG(WARNING) << "Failed to parse field trial param " << param_name
230 << " with string value " << value_as_string 91 << " with string value " << value_as_string
231 << " under feature " << feature.name 92 << " under feature " << feature.name
232 << " into a double. Falling back to default value of " 93 << " into a double. Falling back to default value of "
233 << default_value; 94 << default_value;
234 } 95 }
235 value_as_double = default_value; 96 value_as_double = default_value;
236 } 97 }
237 return value_as_double; 98 return value_as_double;
238 } 99 }
239 100
240 bool GetVariationParamByFeatureAsBool(const base::Feature& feature, 101 bool GetFieldTrialParamByFeatureAsBool(const base::Feature& feature,
241 const std::string& param_name, 102 const std::string& param_name,
242 bool default_value) { 103 bool default_value) {
243 std::string value_as_string = 104 std::string value_as_string =
244 variations::GetVariationParamValueByFeature(feature, param_name); 105 GetFieldTrialParamValueByFeature(feature, param_name);
245 if (value_as_string == "true") 106 if (value_as_string == "true")
246 return true; 107 return true;
247 if (value_as_string == "false") 108 if (value_as_string == "false")
248 return false; 109 return false;
249 110
250 if (!value_as_string.empty()) { 111 if (!value_as_string.empty()) {
251 DLOG(WARNING) << "Failed to parse variation param " << param_name 112 DLOG(WARNING) << "Failed to parse field trial param " << param_name
252 << " with string value " << value_as_string 113 << " with string value " << value_as_string
253 << " under feature " << feature.name 114 << " under feature " << feature.name
254 << " into a bool. Falling back to default value of " 115 << " into a bool. Falling back to default value of "
255 << default_value; 116 << default_value;
256 } 117 }
257 return default_value; 118 return default_value;
258 } 119 }
259 120
260 // Functions below are exposed for testing explicitly behind this namespace. 121 } // namespace base
261 // They simply wrap existing functions in this file.
262 namespace testing {
263
264 void ClearAllVariationIDs() {
265 GroupMapAccessor::GetInstance()->ClearAllMapsForTesting();
266 }
267
268 void ClearAllVariationParams() {
269 base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
270 }
271
272 } // namespace testing
273
274 } // namespace variations
OLDNEW
« no previous file with comments | « base/metrics/field_trial_params.h ('k') | base/metrics/field_trial_params_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698