field_trial_params.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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. #ifndef BASE_METRICS_FIELD_TRIAL_PARAMS_H_
  5. #define BASE_METRICS_FIELD_TRIAL_PARAMS_H_
  6. #include <map>
  7. #include <string>
  8. #include "base/base_export.h"
  9. #include "base/logging.h"
  10. namespace base {
  11. struct Feature;
  12. // Key-value mapping type for field trial parameters.
  13. typedef std::map<std::string, std::string> FieldTrialParams;
  14. // Param string decoding function for AssociateFieldTrialParamsFromString().
  15. typedef std::string (*FieldTrialParamsDecodeStringFunc)(const std::string& str);
  16. // Associates the specified set of key-value |params| with the field trial
  17. // specified by |trial_name| and |group_name|. Fails and returns false if the
  18. // specified field trial already has params associated with it or the trial
  19. // is already active (group() has been called on it). Thread safe.
  20. BASE_EXPORT bool AssociateFieldTrialParams(const std::string& trial_name,
  21. const std::string& group_name,
  22. const FieldTrialParams& params);
  23. // Provides a mechanism to associate multiple set of params to multiple groups
  24. // with a formatted string as returned by FieldTrialList::AllParamsToString().
  25. // |decode_data_func| allows specifying a custom decoding function.
  26. BASE_EXPORT bool AssociateFieldTrialParamsFromString(
  27. const std::string& params_string,
  28. FieldTrialParamsDecodeStringFunc decode_data_func);
  29. // Retrieves the set of key-value |params| for the specified field trial, based
  30. // on its selected group. If the field trial does not exist or its selected
  31. // group does not have any parameters associated with it, returns false and
  32. // does not modify |params|. Calling this function will result in the field
  33. // trial being marked as active if found (i.e. group() will be called on it),
  34. // if it wasn't already. Thread safe.
  35. BASE_EXPORT bool GetFieldTrialParams(const std::string& trial_name,
  36. FieldTrialParams* params);
  37. // Retrieves the set of key-value |params| for the field trial associated with
  38. // the specified |feature|. A feature is associated with at most one field
  39. // trial and selected group. See base/feature_list.h for more information on
  40. // features. If the feature is not enabled, or if there's no associated params,
  41. // returns false and does not modify |params|. Calling this function will
  42. // result in the associated field trial being marked as active if found (i.e.
  43. // group() will be called on it), if it wasn't already. Thread safe.
  44. BASE_EXPORT bool GetFieldTrialParamsByFeature(const base::Feature& feature,
  45. FieldTrialParams* params);
  46. // Retrieves a specific parameter value corresponding to |param_name| for the
  47. // specified field trial, based on its selected group. If the field trial does
  48. // not exist or the specified parameter does not exist, returns an empty
  49. // string. Calling this function will result in the field trial being marked as
  50. // active if found (i.e. group() will be called on it), if it wasn't already.
  51. // Thread safe.
  52. BASE_EXPORT std::string GetFieldTrialParamValue(const std::string& trial_name,
  53. const std::string& param_name);
  54. // Retrieves a specific parameter value corresponding to |param_name| for the
  55. // field trial associated with the specified |feature|. A feature is associated
  56. // with at most one field trial and selected group. See base/feature_list.h for
  57. // more information on features. If the feature is not enabled, or the
  58. // specified parameter does not exist, returns an empty string. Calling this
  59. // function will result in the associated field trial being marked as active if
  60. // found (i.e. group() will be called on it), if it wasn't already. Thread safe.
  61. BASE_EXPORT std::string GetFieldTrialParamValueByFeature(
  62. const base::Feature& feature,
  63. const std::string& param_name);
  64. // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the
  65. // string value into an int using base::StringToInt() and returns it, if
  66. // successful. Otherwise, it returns |default_value|. If the string value is not
  67. // empty and the conversion does not succeed, it produces a warning to LOG.
  68. BASE_EXPORT int GetFieldTrialParamByFeatureAsInt(const base::Feature& feature,
  69. const std::string& param_name,
  70. int default_value);
  71. // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the
  72. // string value into a double using base::StringToDouble() and returns it, if
  73. // successful. Otherwise, it returns |default_value|. If the string value is not
  74. // empty and the conversion does not succeed, it produces a warning to LOG.
  75. BASE_EXPORT double GetFieldTrialParamByFeatureAsDouble(
  76. const base::Feature& feature,
  77. const std::string& param_name,
  78. double default_value);
  79. // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the
  80. // string value into a boolean and returns it, if successful. Otherwise, it
  81. // returns |default_value|. The only string representations accepted here are
  82. // "true" and "false". If the string value is not empty and the conversion does
  83. // not succeed, it produces a warning to LOG.
  84. BASE_EXPORT bool GetFieldTrialParamByFeatureAsBool(
  85. const base::Feature& feature,
  86. const std::string& param_name,
  87. bool default_value);
  88. // Shared declaration for various FeatureParam<T> types.
  89. //
  90. // This template is defined for the following types T:
  91. // bool
  92. // int
  93. // double
  94. // std::string
  95. // enum types
  96. //
  97. // See the individual definitions below for the appropriate interfaces.
  98. // Attempting to use it with any other type is a compile error.
  99. template <typename T, bool IsEnum = std::is_enum<T>::value>
  100. struct FeatureParam {
  101. // Prevent use of FeatureParam<> with unsupported types (e.g. void*). Uses T
  102. // in its definition so that evaluation is deferred until the template is
  103. // instantiated.
  104. static_assert(!std::is_same<T, T>::value, "unsupported FeatureParam<> type");
  105. };
  106. // Declares a string-valued parameter. Example:
  107. //
  108. // constexpr FeatureParam<string> kAssistantName{
  109. // &kAssistantFeature, "assistant_name", "HAL"};
  110. //
  111. // If the feature is not set, or set to the empty string, then Get() will return
  112. // the default value.
  113. template <>
  114. struct FeatureParam<std::string> {
  115. constexpr FeatureParam(const Feature* feature,
  116. const char* name,
  117. const char* default_value)
  118. : feature(feature), name(name), default_value(default_value) {}
  119. BASE_EXPORT std::string Get() const;
  120. const Feature* const feature;
  121. const char* const name;
  122. const char* const default_value;
  123. };
  124. // Declares a double-valued parameter. Example:
  125. //
  126. // constexpr FeatureParam<double> kAssistantTriggerThreshold{
  127. // &kAssistantFeature, "trigger_threshold", 0.10};
  128. //
  129. // If the feature is not set, or set to an invalid double value, then Get() will
  130. // return the default value.
  131. template <>
  132. struct FeatureParam<double> {
  133. constexpr FeatureParam(const Feature* feature,
  134. const char* name,
  135. double default_value)
  136. : feature(feature), name(name), default_value(default_value) {}
  137. BASE_EXPORT double Get() const;
  138. const Feature* const feature;
  139. const char* const name;
  140. const double default_value;
  141. };
  142. // Declares an int-valued parameter. Example:
  143. //
  144. // constexpr FeatureParam<int> kAssistantParallelism{
  145. // &kAssistantFeature, "parallelism", 4};
  146. //
  147. // If the feature is not set, or set to an invalid int value, then Get() will
  148. // return the default value.
  149. template <>
  150. struct FeatureParam<int> {
  151. constexpr FeatureParam(const Feature* feature,
  152. const char* name,
  153. int default_value)
  154. : feature(feature), name(name), default_value(default_value) {}
  155. BASE_EXPORT int Get() const;
  156. const Feature* const feature;
  157. const char* const name;
  158. const int default_value;
  159. };
  160. // Declares a bool-valued parameter. Example:
  161. //
  162. // constexpr FeatureParam<int> kAssistantIsHelpful{
  163. // &kAssistantFeature, "is_helpful", true};
  164. //
  165. // If the feature is not set, or set to value other than "true" or "false", then
  166. // Get() will return the default value.
  167. template <>
  168. struct FeatureParam<bool> {
  169. constexpr FeatureParam(const Feature* feature,
  170. const char* name,
  171. bool default_value)
  172. : feature(feature), name(name), default_value(default_value) {}
  173. BASE_EXPORT bool Get() const;
  174. const Feature* const feature;
  175. const char* const name;
  176. const bool default_value;
  177. };
  178. BASE_EXPORT void LogInvalidEnumValue(const Feature& feature,
  179. const std::string& param_name,
  180. const std::string& value_as_string,
  181. int default_value_as_int);
  182. // Feature param declaration for an enum, with associated options. Example:
  183. //
  184. // constexpr FeatureParam<ShapeEnum>::Option kShapeParamOptions[] = {
  185. // {SHAPE_CIRCLE, "circle"},
  186. // {SHAPE_CYLINDER, "cylinder"},
  187. // {SHAPE_PAPERCLIP, "paperclip"}};
  188. // constexpr FeatureParam<ShapeEnum> kAssistantShapeParam{
  189. // &kAssistantFeature, "shape", SHAPE_CIRCLE, &kShapeParamOptions};
  190. //
  191. // With this declaration, the parameter may be set to "circle", "cylinder", or
  192. // "paperclip", and that will be translated to one of the three enum values. By
  193. // default, or if the param is set to an unknown value, the parameter will be
  194. // assumed to be SHAPE_CIRCLE.
  195. template <typename Enum>
  196. struct FeatureParam<Enum, true> {
  197. struct Option {
  198. constexpr Option(Enum value, const char* name) : value(value), name(name) {}
  199. const Enum value;
  200. const char* const name;
  201. };
  202. template <size_t option_count>
  203. constexpr FeatureParam(const Feature* feature,
  204. const char* name,
  205. const Enum default_value,
  206. const Option (*options)[option_count])
  207. : feature(feature),
  208. name(name),
  209. default_value(default_value),
  210. options(*options),
  211. option_count(option_count) {
  212. static_assert(option_count >= 1, "FeatureParam<enum> has no options");
  213. }
  214. Enum Get() const {
  215. std::string value = GetFieldTrialParamValueByFeature(*feature, name);
  216. if (value.empty())
  217. return default_value;
  218. for (size_t i = 0; i < option_count; ++i) {
  219. if (value == options[i].name)
  220. return options[i].value;
  221. }
  222. LogInvalidEnumValue(*feature, name, value, static_cast<int>(default_value));
  223. return default_value;
  224. }
  225. // Returns the param-string for the given enum value.
  226. std::string GetName(Enum value) const {
  227. for (size_t i = 0; i < option_count; ++i) {
  228. if (value == options[i].value)
  229. return options[i].name;
  230. }
  231. NOTREACHED();
  232. return "";
  233. }
  234. const base::Feature* const feature;
  235. const char* const name;
  236. const Enum default_value;
  237. const Option* const options;
  238. const size_t option_count;
  239. };
  240. } // namespace base
  241. #endif // BASE_METRICS_FIELD_TRIAL_PARAMS_H_