1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_METRICS_FIELD_TRIAL_PARAMS_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_METRICS_FIELD_TRIAL_PARAMS_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <map> 9*6777b538SAndroid Build Coastguard Worker #include <string> 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/feature_list.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/logging.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker namespace base { 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker // Key-value mapping type for field trial parameters. 21*6777b538SAndroid Build Coastguard Worker typedef std::map<std::string, std::string> FieldTrialParams; 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker // Param string decoding function for AssociateFieldTrialParamsFromString(). 24*6777b538SAndroid Build Coastguard Worker typedef std::string (*FieldTrialParamsDecodeStringFunc)(const std::string& str); 25*6777b538SAndroid Build Coastguard Worker 26*6777b538SAndroid Build Coastguard Worker // Unescapes special characters from the given string. Used in 27*6777b538SAndroid Build Coastguard Worker // AssociateFieldTrialParamsFromString() as one of the feature params decoding 28*6777b538SAndroid Build Coastguard Worker // functions. 29*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::string UnescapeValue(const std::string& value); 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker // Associates the specified set of key-value |params| with the field trial 32*6777b538SAndroid Build Coastguard Worker // specified by |trial_name| and |group_name|. Fails and returns false if the 33*6777b538SAndroid Build Coastguard Worker // specified field trial already has params associated with it or the trial 34*6777b538SAndroid Build Coastguard Worker // is already active (group() has been called on it). Thread safe. 35*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool AssociateFieldTrialParams(const std::string& trial_name, 36*6777b538SAndroid Build Coastguard Worker const std::string& group_name, 37*6777b538SAndroid Build Coastguard Worker const FieldTrialParams& params); 38*6777b538SAndroid Build Coastguard Worker 39*6777b538SAndroid Build Coastguard Worker // Provides a mechanism to associate multiple set of params to multiple groups 40*6777b538SAndroid Build Coastguard Worker // with a formatted string as returned by FieldTrialList::AllParamsToString(). 41*6777b538SAndroid Build Coastguard Worker // |decode_data_func| allows specifying a custom decoding function. 42*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool AssociateFieldTrialParamsFromString( 43*6777b538SAndroid Build Coastguard Worker const std::string& params_string, 44*6777b538SAndroid Build Coastguard Worker FieldTrialParamsDecodeStringFunc decode_data_func); 45*6777b538SAndroid Build Coastguard Worker 46*6777b538SAndroid Build Coastguard Worker // Retrieves the set of key-value |params| for the specified field trial, based 47*6777b538SAndroid Build Coastguard Worker // on its selected group. If the field trial does not exist or its selected 48*6777b538SAndroid Build Coastguard Worker // group does not have any parameters associated with it, returns false and 49*6777b538SAndroid Build Coastguard Worker // does not modify |params|. Calling this function will result in the field 50*6777b538SAndroid Build Coastguard Worker // trial being marked as active if found (i.e. group() will be called on it), 51*6777b538SAndroid Build Coastguard Worker // if it wasn't already. Thread safe. 52*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool GetFieldTrialParams(const std::string& trial_name, 53*6777b538SAndroid Build Coastguard Worker FieldTrialParams* params); 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker // Retrieves the set of key-value |params| for the field trial associated with 56*6777b538SAndroid Build Coastguard Worker // the specified |feature|. A feature is associated with at most one field 57*6777b538SAndroid Build Coastguard Worker // trial and selected group. See base/feature_list.h for more information on 58*6777b538SAndroid Build Coastguard Worker // features. If the feature is not enabled, or if there's no associated params, 59*6777b538SAndroid Build Coastguard Worker // returns false and does not modify |params|. Calling this function will 60*6777b538SAndroid Build Coastguard Worker // result in the associated field trial being marked as active if found (i.e. 61*6777b538SAndroid Build Coastguard Worker // group() will be called on it), if it wasn't already. Thread safe. 62*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool GetFieldTrialParamsByFeature(const base::Feature& feature, 63*6777b538SAndroid Build Coastguard Worker FieldTrialParams* params); 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // Retrieves a specific parameter value corresponding to |param_name| for the 66*6777b538SAndroid Build Coastguard Worker // specified field trial, based on its selected group. If the field trial does 67*6777b538SAndroid Build Coastguard Worker // not exist or the specified parameter does not exist, returns an empty 68*6777b538SAndroid Build Coastguard Worker // string. Calling this function will result in the field trial being marked as 69*6777b538SAndroid Build Coastguard Worker // active if found (i.e. group() will be called on it), if it wasn't already. 70*6777b538SAndroid Build Coastguard Worker // Thread safe. 71*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::string GetFieldTrialParamValue(const std::string& trial_name, 72*6777b538SAndroid Build Coastguard Worker const std::string& param_name); 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker // Retrieves a specific parameter value corresponding to |param_name| for the 75*6777b538SAndroid Build Coastguard Worker // field trial associated with the specified |feature|. A feature is associated 76*6777b538SAndroid Build Coastguard Worker // with at most one field trial and selected group. See base/feature_list.h for 77*6777b538SAndroid Build Coastguard Worker // more information on features. If the feature is not enabled, or the 78*6777b538SAndroid Build Coastguard Worker // specified parameter does not exist, returns an empty string. Calling this 79*6777b538SAndroid Build Coastguard Worker // function will result in the associated field trial being marked as active if 80*6777b538SAndroid Build Coastguard Worker // found (i.e. group() will be called on it), if it wasn't already. Thread safe. 81*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::string GetFieldTrialParamValueByFeature( 82*6777b538SAndroid Build Coastguard Worker const base::Feature& feature, 83*6777b538SAndroid Build Coastguard Worker const std::string& param_name); 84*6777b538SAndroid Build Coastguard Worker 85*6777b538SAndroid Build Coastguard Worker // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the 86*6777b538SAndroid Build Coastguard Worker // string value into an int using base::StringToInt() and returns it, if 87*6777b538SAndroid Build Coastguard Worker // successful. Otherwise, it returns |default_value|. If the string value is not 88*6777b538SAndroid Build Coastguard Worker // empty and the conversion does not succeed, it produces a warning to LOG. 89*6777b538SAndroid Build Coastguard Worker BASE_EXPORT int GetFieldTrialParamByFeatureAsInt(const base::Feature& feature, 90*6777b538SAndroid Build Coastguard Worker const std::string& param_name, 91*6777b538SAndroid Build Coastguard Worker int default_value); 92*6777b538SAndroid Build Coastguard Worker 93*6777b538SAndroid Build Coastguard Worker // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the 94*6777b538SAndroid Build Coastguard Worker // string value into a double using base::StringToDouble() and returns it, if 95*6777b538SAndroid Build Coastguard Worker // successful. Otherwise, it returns |default_value|. If the string value is not 96*6777b538SAndroid Build Coastguard Worker // empty and the conversion does not succeed, it produces a warning to LOG. 97*6777b538SAndroid Build Coastguard Worker BASE_EXPORT double GetFieldTrialParamByFeatureAsDouble( 98*6777b538SAndroid Build Coastguard Worker const base::Feature& feature, 99*6777b538SAndroid Build Coastguard Worker const std::string& param_name, 100*6777b538SAndroid Build Coastguard Worker double default_value); 101*6777b538SAndroid Build Coastguard Worker 102*6777b538SAndroid Build Coastguard Worker // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the 103*6777b538SAndroid Build Coastguard Worker // string value into a boolean and returns it, if successful. Otherwise, it 104*6777b538SAndroid Build Coastguard Worker // returns |default_value|. The only string representations accepted here are 105*6777b538SAndroid Build Coastguard Worker // "true" and "false". If the string value is not empty and the conversion does 106*6777b538SAndroid Build Coastguard Worker // not succeed, it produces a warning to LOG. 107*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool GetFieldTrialParamByFeatureAsBool( 108*6777b538SAndroid Build Coastguard Worker const base::Feature& feature, 109*6777b538SAndroid Build Coastguard Worker const std::string& param_name, 110*6777b538SAndroid Build Coastguard Worker bool default_value); 111*6777b538SAndroid Build Coastguard Worker 112*6777b538SAndroid Build Coastguard Worker // Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the 113*6777b538SAndroid Build Coastguard Worker // string value into a base::TimeDelta and returns it, if successful. Otherwise, 114*6777b538SAndroid Build Coastguard Worker // it returns `default_value`. If the string value is not empty and the 115*6777b538SAndroid Build Coastguard Worker // conversion does not succeed, it produces a warning to LOG. 116*6777b538SAndroid Build Coastguard Worker BASE_EXPORT base::TimeDelta GetFieldTrialParamByFeatureAsTimeDelta( 117*6777b538SAndroid Build Coastguard Worker const Feature& feature, 118*6777b538SAndroid Build Coastguard Worker const std::string& param_name, 119*6777b538SAndroid Build Coastguard Worker base::TimeDelta default_value); 120*6777b538SAndroid Build Coastguard Worker 121*6777b538SAndroid Build Coastguard Worker // Shared declaration for various FeatureParam<T> types. 122*6777b538SAndroid Build Coastguard Worker // 123*6777b538SAndroid Build Coastguard Worker // This template is defined for the following types T: 124*6777b538SAndroid Build Coastguard Worker // bool 125*6777b538SAndroid Build Coastguard Worker // int 126*6777b538SAndroid Build Coastguard Worker // double 127*6777b538SAndroid Build Coastguard Worker // std::string 128*6777b538SAndroid Build Coastguard Worker // enum types 129*6777b538SAndroid Build Coastguard Worker // base::TimeDelta 130*6777b538SAndroid Build Coastguard Worker // 131*6777b538SAndroid Build Coastguard Worker // See the individual definitions below for the appropriate interfaces. 132*6777b538SAndroid Build Coastguard Worker // Attempting to use it with any other type is a compile error. 133*6777b538SAndroid Build Coastguard Worker // 134*6777b538SAndroid Build Coastguard Worker // Getting a param value from a FeatureParam<T> will have the same semantics as 135*6777b538SAndroid Build Coastguard Worker // GetFieldTrialParamValueByFeature(), see that function's comments for details. 136*6777b538SAndroid Build Coastguard Worker template <typename T, bool IsEnum = std::is_enum_v<T>> 137*6777b538SAndroid Build Coastguard Worker struct FeatureParam { 138*6777b538SAndroid Build Coastguard Worker // Prevent use of FeatureParam<> with unsupported types (e.g. void*). Uses T 139*6777b538SAndroid Build Coastguard Worker // in its definition so that evaluation is deferred until the template is 140*6777b538SAndroid Build Coastguard Worker // instantiated. 141*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_same_v<T, T>, "unsupported FeatureParam<> type"); 142*6777b538SAndroid Build Coastguard Worker }; 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker // Declares a string-valued parameter. Example: 145*6777b538SAndroid Build Coastguard Worker // 146*6777b538SAndroid Build Coastguard Worker // constexpr FeatureParam<string> kAssistantName{ 147*6777b538SAndroid Build Coastguard Worker // &kAssistantFeature, "assistant_name", "HAL"}; 148*6777b538SAndroid Build Coastguard Worker // 149*6777b538SAndroid Build Coastguard Worker // If the feature is not enabled, the parameter is not set, or set to the empty 150*6777b538SAndroid Build Coastguard Worker // string, then Get() will return the default value. 151*6777b538SAndroid Build Coastguard Worker template <> 152*6777b538SAndroid Build Coastguard Worker struct FeatureParam<std::string> { 153*6777b538SAndroid Build Coastguard Worker constexpr FeatureParam(const Feature* feature, 154*6777b538SAndroid Build Coastguard Worker const char* name, 155*6777b538SAndroid Build Coastguard Worker const char* default_value) 156*6777b538SAndroid Build Coastguard Worker : feature(feature), name(name), default_value(default_value) {} 157*6777b538SAndroid Build Coastguard Worker 158*6777b538SAndroid Build Coastguard Worker // Calling Get() will activate the field trial associated with |feature|. See 159*6777b538SAndroid Build Coastguard Worker // GetFieldTrialParamValueByFeature() for more details. 160*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::string Get() const; 161*6777b538SAndroid Build Coastguard Worker 162*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter for: 163*6777b538SAndroid Build Coastguard Worker // #global-scope, #constexpr-ctor-field-initializer 164*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const Feature* const feature; 165*6777b538SAndroid Build Coastguard Worker const char* const name; 166*6777b538SAndroid Build Coastguard Worker const char* const default_value; 167*6777b538SAndroid Build Coastguard Worker }; 168*6777b538SAndroid Build Coastguard Worker 169*6777b538SAndroid Build Coastguard Worker // Declares a double-valued parameter. Example: 170*6777b538SAndroid Build Coastguard Worker // 171*6777b538SAndroid Build Coastguard Worker // constexpr FeatureParam<double> kAssistantTriggerThreshold{ 172*6777b538SAndroid Build Coastguard Worker // &kAssistantFeature, "trigger_threshold", 0.10}; 173*6777b538SAndroid Build Coastguard Worker // 174*6777b538SAndroid Build Coastguard Worker // If the feature is not enabled, the parameter is not set, or set to an invalid 175*6777b538SAndroid Build Coastguard Worker // double value, then Get() will return the default value. 176*6777b538SAndroid Build Coastguard Worker template <> 177*6777b538SAndroid Build Coastguard Worker struct FeatureParam<double> { 178*6777b538SAndroid Build Coastguard Worker constexpr FeatureParam(const Feature* feature, 179*6777b538SAndroid Build Coastguard Worker const char* name, 180*6777b538SAndroid Build Coastguard Worker double default_value) 181*6777b538SAndroid Build Coastguard Worker : feature(feature), name(name), default_value(default_value) {} 182*6777b538SAndroid Build Coastguard Worker 183*6777b538SAndroid Build Coastguard Worker // Calling Get() will activate the field trial associated with |feature|. See 184*6777b538SAndroid Build Coastguard Worker // GetFieldTrialParamValueByFeature() for more details. 185*6777b538SAndroid Build Coastguard Worker BASE_EXPORT double Get() const; 186*6777b538SAndroid Build Coastguard Worker 187*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter for: 188*6777b538SAndroid Build Coastguard Worker // #global-scope, #constexpr-ctor-field-initializer 189*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const Feature* const feature; 190*6777b538SAndroid Build Coastguard Worker const char* const name; 191*6777b538SAndroid Build Coastguard Worker const double default_value; 192*6777b538SAndroid Build Coastguard Worker }; 193*6777b538SAndroid Build Coastguard Worker 194*6777b538SAndroid Build Coastguard Worker // Declares an int-valued parameter. Example: 195*6777b538SAndroid Build Coastguard Worker // 196*6777b538SAndroid Build Coastguard Worker // constexpr FeatureParam<int> kAssistantParallelism{ 197*6777b538SAndroid Build Coastguard Worker // &kAssistantFeature, "parallelism", 4}; 198*6777b538SAndroid Build Coastguard Worker // 199*6777b538SAndroid Build Coastguard Worker // If the feature is not enabled, the parameter is not set, or set to an invalid 200*6777b538SAndroid Build Coastguard Worker // int value, then Get() will return the default value. 201*6777b538SAndroid Build Coastguard Worker template <> 202*6777b538SAndroid Build Coastguard Worker struct FeatureParam<int> { 203*6777b538SAndroid Build Coastguard Worker constexpr FeatureParam(const Feature* feature, 204*6777b538SAndroid Build Coastguard Worker const char* name, 205*6777b538SAndroid Build Coastguard Worker int default_value) 206*6777b538SAndroid Build Coastguard Worker : feature(feature), name(name), default_value(default_value) {} 207*6777b538SAndroid Build Coastguard Worker 208*6777b538SAndroid Build Coastguard Worker // Calling Get() will activate the field trial associated with |feature|. See 209*6777b538SAndroid Build Coastguard Worker // GetFieldTrialParamValueByFeature() for more details. 210*6777b538SAndroid Build Coastguard Worker BASE_EXPORT int Get() const; 211*6777b538SAndroid Build Coastguard Worker 212*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter for: 213*6777b538SAndroid Build Coastguard Worker // #global-scope, #constexpr-ctor-field-initializer 214*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const Feature* const feature; 215*6777b538SAndroid Build Coastguard Worker const char* const name; 216*6777b538SAndroid Build Coastguard Worker const int default_value; 217*6777b538SAndroid Build Coastguard Worker }; 218*6777b538SAndroid Build Coastguard Worker 219*6777b538SAndroid Build Coastguard Worker // Declares a bool-valued parameter. Example: 220*6777b538SAndroid Build Coastguard Worker // 221*6777b538SAndroid Build Coastguard Worker // constexpr FeatureParam<int> kAssistantIsHelpful{ 222*6777b538SAndroid Build Coastguard Worker // &kAssistantFeature, "is_helpful", true}; 223*6777b538SAndroid Build Coastguard Worker // 224*6777b538SAndroid Build Coastguard Worker // If the feature is not enabled, the parameter is not set, or set to value 225*6777b538SAndroid Build Coastguard Worker // other than "true" or "false", then Get() will return the default value. 226*6777b538SAndroid Build Coastguard Worker template <> 227*6777b538SAndroid Build Coastguard Worker struct FeatureParam<bool> { 228*6777b538SAndroid Build Coastguard Worker constexpr FeatureParam(const Feature* feature, 229*6777b538SAndroid Build Coastguard Worker const char* name, 230*6777b538SAndroid Build Coastguard Worker bool default_value) 231*6777b538SAndroid Build Coastguard Worker : feature(feature), name(name), default_value(default_value) {} 232*6777b538SAndroid Build Coastguard Worker 233*6777b538SAndroid Build Coastguard Worker // Calling Get() will activate the field trial associated with |feature|. See 234*6777b538SAndroid Build Coastguard Worker // GetFieldTrialParamValueByFeature() for more details. 235*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool Get() const; 236*6777b538SAndroid Build Coastguard Worker 237*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter for: 238*6777b538SAndroid Build Coastguard Worker // #global-scope, #constexpr-ctor-field-initializer 239*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const Feature* const feature; 240*6777b538SAndroid Build Coastguard Worker const char* const name; 241*6777b538SAndroid Build Coastguard Worker const bool default_value; 242*6777b538SAndroid Build Coastguard Worker }; 243*6777b538SAndroid Build Coastguard Worker 244*6777b538SAndroid Build Coastguard Worker // Declares an TimeDelta-valued parameter. Example: 245*6777b538SAndroid Build Coastguard Worker // 246*6777b538SAndroid Build Coastguard Worker // constexpr base::FeatureParam<base::TimeDelta> kPerAgentDelay{ 247*6777b538SAndroid Build Coastguard Worker // &kPerAgentSchedulingExperiments, "delay", base::TimeDelta()}; 248*6777b538SAndroid Build Coastguard Worker // 249*6777b538SAndroid Build Coastguard Worker // If the feature is not enabled, the parameter is not set, or set to an 250*6777b538SAndroid Build Coastguard Worker // invalid value (as defined by base::TimeDeltaFromString()), then Get() will 251*6777b538SAndroid Build Coastguard Worker // return the default value. 252*6777b538SAndroid Build Coastguard Worker template <> 253*6777b538SAndroid Build Coastguard Worker struct FeatureParam<base::TimeDelta> { 254*6777b538SAndroid Build Coastguard Worker constexpr FeatureParam(const Feature* feature, 255*6777b538SAndroid Build Coastguard Worker const char* name, 256*6777b538SAndroid Build Coastguard Worker base::TimeDelta default_value) 257*6777b538SAndroid Build Coastguard Worker : feature(feature), name(name), default_value(default_value) {} 258*6777b538SAndroid Build Coastguard Worker 259*6777b538SAndroid Build Coastguard Worker // Calling Get() will activate the field trial associated with |feature|. See 260*6777b538SAndroid Build Coastguard Worker // GetFieldTrialParamValueByFeature() for more details. 261*6777b538SAndroid Build Coastguard Worker BASE_EXPORT base::TimeDelta Get() const; 262*6777b538SAndroid Build Coastguard Worker 263*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter for: 264*6777b538SAndroid Build Coastguard Worker // #global-scope, #constexpr-ctor-field-initializer 265*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const Feature* const feature; 266*6777b538SAndroid Build Coastguard Worker const char* const name; 267*6777b538SAndroid Build Coastguard Worker const base::TimeDelta default_value; 268*6777b538SAndroid Build Coastguard Worker }; 269*6777b538SAndroid Build Coastguard Worker 270*6777b538SAndroid Build Coastguard Worker BASE_EXPORT void LogInvalidEnumValue(const Feature& feature, 271*6777b538SAndroid Build Coastguard Worker const std::string& param_name, 272*6777b538SAndroid Build Coastguard Worker const std::string& value_as_string, 273*6777b538SAndroid Build Coastguard Worker int default_value_as_int); 274*6777b538SAndroid Build Coastguard Worker 275*6777b538SAndroid Build Coastguard Worker // Feature param declaration for an enum, with associated options. Example: 276*6777b538SAndroid Build Coastguard Worker // 277*6777b538SAndroid Build Coastguard Worker // constexpr FeatureParam<ShapeEnum>::Option kShapeParamOptions[] = { 278*6777b538SAndroid Build Coastguard Worker // {SHAPE_CIRCLE, "circle"}, 279*6777b538SAndroid Build Coastguard Worker // {SHAPE_CYLINDER, "cylinder"}, 280*6777b538SAndroid Build Coastguard Worker // {SHAPE_PAPERCLIP, "paperclip"}}; 281*6777b538SAndroid Build Coastguard Worker // constexpr FeatureParam<ShapeEnum> kAssistantShapeParam{ 282*6777b538SAndroid Build Coastguard Worker // &kAssistantFeature, "shape", SHAPE_CIRCLE, &kShapeParamOptions}; 283*6777b538SAndroid Build Coastguard Worker // 284*6777b538SAndroid Build Coastguard Worker // With this declaration, the parameter may be set to "circle", "cylinder", or 285*6777b538SAndroid Build Coastguard Worker // "paperclip", and that will be translated to one of the three enum values. By 286*6777b538SAndroid Build Coastguard Worker // default, or if the param is set to an unknown value, the parameter will be 287*6777b538SAndroid Build Coastguard Worker // assumed to be SHAPE_CIRCLE. 288*6777b538SAndroid Build Coastguard Worker template <typename Enum> 289*6777b538SAndroid Build Coastguard Worker struct FeatureParam<Enum, true> { 290*6777b538SAndroid Build Coastguard Worker struct Option { 291*6777b538SAndroid Build Coastguard Worker constexpr Option(Enum value, const char* name) : value(value), name(name) {} 292*6777b538SAndroid Build Coastguard Worker 293*6777b538SAndroid Build Coastguard Worker const Enum value; 294*6777b538SAndroid Build Coastguard Worker const char* const name; 295*6777b538SAndroid Build Coastguard Worker }; 296*6777b538SAndroid Build Coastguard Worker 297*6777b538SAndroid Build Coastguard Worker template <size_t option_count> 298*6777b538SAndroid Build Coastguard Worker constexpr FeatureParam(const Feature* feature, 299*6777b538SAndroid Build Coastguard Worker const char* name, 300*6777b538SAndroid Build Coastguard Worker const Enum default_value, 301*6777b538SAndroid Build Coastguard Worker const Option (*options)[option_count]) 302*6777b538SAndroid Build Coastguard Worker : feature(feature), 303*6777b538SAndroid Build Coastguard Worker name(name), 304*6777b538SAndroid Build Coastguard Worker default_value(default_value), 305*6777b538SAndroid Build Coastguard Worker options(*options), 306*6777b538SAndroid Build Coastguard Worker option_count(option_count) { 307*6777b538SAndroid Build Coastguard Worker static_assert(option_count >= 1, "FeatureParam<enum> has no options"); 308*6777b538SAndroid Build Coastguard Worker } 309*6777b538SAndroid Build Coastguard Worker 310*6777b538SAndroid Build Coastguard Worker // Calling Get() will activate the field trial associated with |feature|. See 311*6777b538SAndroid Build Coastguard Worker // GetFieldTrialParamValueByFeature() for more details. 312*6777b538SAndroid Build Coastguard Worker Enum Get() const { 313*6777b538SAndroid Build Coastguard Worker std::string value = GetFieldTrialParamValueByFeature(*feature, name); 314*6777b538SAndroid Build Coastguard Worker if (value.empty()) 315*6777b538SAndroid Build Coastguard Worker return default_value; 316*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < option_count; ++i) { 317*6777b538SAndroid Build Coastguard Worker if (value == options[i].name) 318*6777b538SAndroid Build Coastguard Worker return options[i].value; 319*6777b538SAndroid Build Coastguard Worker } 320*6777b538SAndroid Build Coastguard Worker LogInvalidEnumValue(*feature, name, value, static_cast<int>(default_value)); 321*6777b538SAndroid Build Coastguard Worker return default_value; 322*6777b538SAndroid Build Coastguard Worker } 323*6777b538SAndroid Build Coastguard Worker 324*6777b538SAndroid Build Coastguard Worker // Returns the param-string for the given enum value. 325*6777b538SAndroid Build Coastguard Worker std::string GetName(Enum value) const { 326*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < option_count; ++i) { 327*6777b538SAndroid Build Coastguard Worker if (value == options[i].value) 328*6777b538SAndroid Build Coastguard Worker return options[i].name; 329*6777b538SAndroid Build Coastguard Worker } 330*6777b538SAndroid Build Coastguard Worker NOTREACHED(); 331*6777b538SAndroid Build Coastguard Worker return ""; 332*6777b538SAndroid Build Coastguard Worker } 333*6777b538SAndroid Build Coastguard Worker 334*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter for: 335*6777b538SAndroid Build Coastguard Worker // #global-scope, #constexpr-ctor-field-initializer 336*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const base::Feature* const feature; 337*6777b538SAndroid Build Coastguard Worker const char* const name; 338*6777b538SAndroid Build Coastguard Worker const Enum default_value; 339*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it was filtered by the rewriter for: 340*6777b538SAndroid Build Coastguard Worker // #global-scope, #constexpr-ctor-field-initializer 341*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION const Option* const options; 342*6777b538SAndroid Build Coastguard Worker const size_t option_count; 343*6777b538SAndroid Build Coastguard Worker }; 344*6777b538SAndroid Build Coastguard Worker 345*6777b538SAndroid Build Coastguard Worker } // namespace base 346*6777b538SAndroid Build Coastguard Worker 347*6777b538SAndroid Build Coastguard Worker #endif // BASE_METRICS_FIELD_TRIAL_PARAMS_H_ 348