| OLD | NEW |
| 1 // Copyright 2017 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/feature_engagement_tracker/internal/chrome_variations_confi
guration.h" | 5 #include "components/feature_engagement_tracker/internal/chrome_variations_confi
guration.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <tuple> | 10 #include <tuple> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/metrics/field_trial_params.h" | 15 #include "base/metrics/field_trial_params.h" |
| 16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/string_piece.h" | 17 #include "base/strings/string_piece.h" |
| 18 #include "base/strings/string_split.h" | 18 #include "base/strings/string_split.h" |
| 19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 20 #include "components/feature_engagement_tracker/internal/configuration.h" | 20 #include "components/feature_engagement_tracker/internal/configuration.h" |
| 21 #include "components/feature_engagement_tracker/internal/stats.h" |
| 21 #include "components/feature_engagement_tracker/public/feature_list.h" | 22 #include "components/feature_engagement_tracker/public/feature_list.h" |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 const char kComparatorTypeAny[] = "any"; | 26 const char kComparatorTypeAny[] = "any"; |
| 26 const char kComparatorTypeLessThan[] = "<"; | 27 const char kComparatorTypeLessThan[] = "<"; |
| 27 const char kComparatorTypeGreaterThan[] = ">"; | 28 const char kComparatorTypeGreaterThan[] = ">"; |
| 28 const char kComparatorTypeLessThanOrEqual[] = "<="; | 29 const char kComparatorTypeLessThanOrEqual[] = "<="; |
| 29 const char kComparatorTypeGreaterThanOrEqual[] = ">="; | 30 const char kComparatorTypeGreaterThanOrEqual[] = ">="; |
| 30 const char kComparatorTypeEqual[] = "=="; | 31 const char kComparatorTypeEqual[] = "=="; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 DCHECK(feature); | 205 DCHECK(feature); |
| 205 DCHECK(configs_.find(feature) == configs_.end()); | 206 DCHECK(configs_.find(feature) == configs_.end()); |
| 206 | 207 |
| 207 // Initially all new configurations are considered invalid. | 208 // Initially all new configurations are considered invalid. |
| 208 FeatureConfig& config = configs_[feature]; | 209 FeatureConfig& config = configs_[feature]; |
| 209 config.valid = false; | 210 config.valid = false; |
| 210 uint32_t parse_errors = 0; | 211 uint32_t parse_errors = 0; |
| 211 | 212 |
| 212 std::map<std::string, std::string> params; | 213 std::map<std::string, std::string> params; |
| 213 bool result = base::GetFieldTrialParamsByFeature(*feature, ¶ms); | 214 bool result = base::GetFieldTrialParamsByFeature(*feature, ¶ms); |
| 214 if (!result) | 215 if (!result) { |
| 216 stats::RecordConfigParsingEvent( |
| 217 stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL); |
| 218 // Returns early. If no field trial, ConfigParsingEvent::FAILURE will not be |
| 219 // recorded. |
| 215 return; | 220 return; |
| 221 } |
| 216 | 222 |
| 217 for (const auto& it : params) { | 223 for (const auto& it : params) { |
| 218 const std::string& key = it.first; | 224 const std::string& key = it.first; |
| 219 if (key == kEventConfigUsedKey) { | 225 if (key == kEventConfigUsedKey) { |
| 220 EventConfig event_config; | 226 EventConfig event_config; |
| 221 if (!ParseEventConfig(params[key], &event_config)) { | 227 if (!ParseEventConfig(params[key], &event_config)) { |
| 222 ++parse_errors; | 228 ++parse_errors; |
| 229 stats::RecordConfigParsingEvent( |
| 230 stats::ConfigParsingEvent::FAILURE_USED_EVENT_PARSE); |
| 223 continue; | 231 continue; |
| 224 } | 232 } |
| 225 config.used = event_config; | 233 config.used = event_config; |
| 226 } else if (key == kEventConfigTriggerKey) { | 234 } else if (key == kEventConfigTriggerKey) { |
| 227 EventConfig event_config; | 235 EventConfig event_config; |
| 228 if (!ParseEventConfig(params[key], &event_config)) { | 236 if (!ParseEventConfig(params[key], &event_config)) { |
| 237 stats::RecordConfigParsingEvent( |
| 238 stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_PARSE); |
| 229 ++parse_errors; | 239 ++parse_errors; |
| 230 continue; | 240 continue; |
| 231 } | 241 } |
| 232 config.trigger = event_config; | 242 config.trigger = event_config; |
| 233 } else if (key == kSessionRateKey) { | 243 } else if (key == kSessionRateKey) { |
| 234 Comparator comparator; | 244 Comparator comparator; |
| 235 if (!ParseComparator(params[key], &comparator)) { | 245 if (!ParseComparator(params[key], &comparator)) { |
| 246 stats::RecordConfigParsingEvent( |
| 247 stats::ConfigParsingEvent::FAILURE_SESSION_RATE_PARSE); |
| 236 ++parse_errors; | 248 ++parse_errors; |
| 237 continue; | 249 continue; |
| 238 } | 250 } |
| 239 config.session_rate = comparator; | 251 config.session_rate = comparator; |
| 240 } else if (key == kAvailabilityKey) { | 252 } else if (key == kAvailabilityKey) { |
| 241 Comparator comparator; | 253 Comparator comparator; |
| 242 if (!ParseComparator(params[key], &comparator)) { | 254 if (!ParseComparator(params[key], &comparator)) { |
| 255 stats::RecordConfigParsingEvent( |
| 256 stats::ConfigParsingEvent::FAILURE_AVAILABILITY_PARSE); |
| 243 ++parse_errors; | 257 ++parse_errors; |
| 244 continue; | 258 continue; |
| 245 } | 259 } |
| 246 config.availability = comparator; | 260 config.availability = comparator; |
| 247 } else if (base::StartsWith(key, kEventConfigKeyPrefix, | 261 } else if (base::StartsWith(key, kEventConfigKeyPrefix, |
| 248 base::CompareCase::INSENSITIVE_ASCII)) { | 262 base::CompareCase::INSENSITIVE_ASCII)) { |
| 249 EventConfig event_config; | 263 EventConfig event_config; |
| 250 if (!ParseEventConfig(params[key], &event_config)) { | 264 if (!ParseEventConfig(params[key], &event_config)) { |
| 265 stats::RecordConfigParsingEvent( |
| 266 stats::ConfigParsingEvent::FAILURE_OTHER_EVENT_PARSE); |
| 251 ++parse_errors; | 267 ++parse_errors; |
| 252 continue; | 268 continue; |
| 253 } | 269 } |
| 254 config.event_configs.insert(event_config); | 270 config.event_configs.insert(event_config); |
| 255 } else { | 271 } else { |
| 256 DVLOG(1) << "Ignoring unknown key when parsing config for feature " | 272 DVLOG(1) << "Ignoring unknown key when parsing config for feature " |
| 257 << feature->name << ": " << key; | 273 << feature->name << ": " << key; |
| 274 stats::RecordConfigParsingEvent( |
| 275 stats::ConfigParsingEvent::FAILURE_UNKNOWN_KEY); |
| 258 } | 276 } |
| 259 } | 277 } |
| 260 | 278 |
| 261 // The |used| and |trigger| members are required, so should not be the | 279 // The |used| and |trigger| members are required, so should not be the |
| 262 // default values. | 280 // default values. |
| 263 config.valid = config.used != EventConfig() && | 281 bool has_used_event = config.used != EventConfig(); |
| 264 config.trigger != EventConfig() && parse_errors == 0; | 282 bool has_trigger_event = config.trigger != EventConfig(); |
| 283 config.valid = has_used_event && has_trigger_event && parse_errors == 0; |
| 284 |
| 285 if (config.valid) { |
| 286 stats::RecordConfigParsingEvent(stats::ConfigParsingEvent::SUCCESS); |
| 287 } else { |
| 288 stats::RecordConfigParsingEvent(stats::ConfigParsingEvent::FAILURE); |
| 289 } |
| 290 |
| 291 // Notice parse errors for used and trigger events will also cause the |
| 292 // following histograms being recorded. |
| 293 if (!has_used_event) { |
| 294 stats::RecordConfigParsingEvent( |
| 295 stats::ConfigParsingEvent::FAILURE_USED_EVENT_MISSING); |
| 296 } |
| 297 if (!has_trigger_event) { |
| 298 stats::RecordConfigParsingEvent( |
| 299 stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_MISSING); |
| 300 } |
| 265 } | 301 } |
| 266 | 302 |
| 267 const FeatureConfig& ChromeVariationsConfiguration::GetFeatureConfig( | 303 const FeatureConfig& ChromeVariationsConfiguration::GetFeatureConfig( |
| 268 const base::Feature& feature) const { | 304 const base::Feature& feature) const { |
| 269 auto it = configs_.find(&feature); | 305 auto it = configs_.find(&feature); |
| 270 DCHECK(it != configs_.end()); | 306 DCHECK(it != configs_.end()); |
| 271 return it->second; | 307 return it->second; |
| 272 } | 308 } |
| 273 | 309 |
| 310 const Configuration::ConfigMap& |
| 311 ChromeVariationsConfiguration::GetRegisteredFeatures() const { |
| 312 return configs_; |
| 313 } |
| 314 |
| 274 } // namespace feature_engagement_tracker | 315 } // namespace feature_engagement_tracker |
| OLD | NEW |