autofill_metrics.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
1// Copyright 2013 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/autofill/core/browser/autofill_metrics.h" 6 7#include "base/logging.h" 8#include "base/metrics/histogram.h" 9#include "base/time/time.h" 10#include "components/autofill/core/browser/autofill_type.h" 11#include "components/autofill/core/browser/form_structure.h" 12#include "components/autofill/core/common/form_data.h" 13 14namespace autofill { 15 16namespace { 17 18// Server experiments we support. 19enum ServerExperiment { 20 NO_EXPERIMENT = 0, 21 UNKNOWN_EXPERIMENT, 22 ACCEPTANCE_RATIO_06, 23 ACCEPTANCE_RATIO_1, 24 ACCEPTANCE_RATIO_2, 25 ACCEPTANCE_RATIO_4, 26 ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15, 27 ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_25, 28 ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15_MIN_FORM_SCORE_5, 29 TOOLBAR_DATA_ONLY, 30 ACCEPTANCE_RATIO_04_WINNER_LEAD_RATIO_3_MIN_FORM_SCORE_4, 31 NO_SERVER_RESPONSE, 32 PROBABILITY_PICKER_05, 33 PROBABILITY_PICKER_025, 34 PROBABILITY_PICKER_025_CC_THRESHOLD_03, 35 PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03, 36 PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03_WITH_FALLBACK, 37 PROBABILITY_PICKER_05_CC_NAME_THRESHOLD_03_EXPERIMENT_1, 38 NUM_SERVER_EXPERIMENTS 39}; 40 41enum FieldTypeGroupForMetrics { 42 AMBIGUOUS = 0, 43 NAME, 44 COMPANY, 45 ADDRESS_LINE_1, 46 ADDRESS_LINE_2, 47 ADDRESS_CITY, 48 ADDRESS_STATE, 49 ADDRESS_ZIP, 50 ADDRESS_COUNTRY, 51 PHONE, 52 FAX, // Deprecated. 53 EMAIL, 54 CREDIT_CARD_NAME, 55 CREDIT_CARD_NUMBER, 56 CREDIT_CARD_DATE, 57 CREDIT_CARD_TYPE, 58 NUM_FIELD_TYPE_GROUPS_FOR_METRICS 59}; 60 61// First, translates |field_type| to the corresponding logical |group| from 62// |FieldTypeGroupForMetrics|. Then, interpolates this with the given |metric|, 63// which should be in the range [0, |num_possible_metrics|). 64// Returns the interpolated index. 65// 66// The interpolation maps the pair (|group|, |metric|) to a single index, so 67// that all the indicies for a given group are adjacent. In particular, with 68// the groups {AMBIGUOUS, NAME, ...} combining with the metrics {UNKNOWN, MATCH, 69// MISMATCH}, we create this set of mapped indices: 70// { 71// AMBIGUOUS+UNKNOWN, 72// AMBIGUOUS+MATCH, 73// AMBIGUOUS+MISMATCH, 74// NAME+UNKNOWN, 75// NAME+MATCH, 76// NAME+MISMATCH, 77// ... 78// }. 79// 80// Clients must ensure that |field_type| is one of the types Chrome supports 81// natively, e.g. |field_type| must not be a billng address. 82int GetFieldTypeGroupMetric(const ServerFieldType field_type, 83 const int metric, 84 const int num_possible_metrics) { 85 DCHECK_LT(metric, num_possible_metrics); 86 87 FieldTypeGroupForMetrics group; 88 switch (AutofillType(field_type).group()) { 89 case ::autofill::NO_GROUP: 90 group = AMBIGUOUS; 91 break; 92 93 case ::autofill::NAME: 94 group = NAME; 95 break; 96 97 case ::autofill::COMPANY: 98 group = COMPANY; 99 break; 100 101 case ::autofill::ADDRESS_HOME: 102 switch (field_type) { 103 case ADDRESS_HOME_LINE1: 104 group = ADDRESS_LINE_1; 105 break; 106 case ADDRESS_HOME_LINE2: 107 group = ADDRESS_LINE_2; 108 break; 109 case ADDRESS_HOME_CITY: 110 group = ADDRESS_CITY; 111 break; 112 case ADDRESS_HOME_STATE: 113 group = ADDRESS_STATE; 114 break; 115 case ADDRESS_HOME_ZIP: 116 group = ADDRESS_ZIP; 117 break; 118 case ADDRESS_HOME_COUNTRY: 119 group = ADDRESS_COUNTRY; 120 break; 121 default: 122 NOTREACHED(); 123 group = AMBIGUOUS; 124 } 125 break; 126 127 case ::autofill::EMAIL: 128 group = EMAIL; 129 break; 130 131 case ::autofill::PHONE_HOME: 132 group = PHONE; 133 break; 134 135 case ::autofill::CREDIT_CARD: 136 switch (field_type) { 137 case ::autofill::CREDIT_CARD_NAME: 138 group = CREDIT_CARD_NAME; 139 break; 140 case ::autofill::CREDIT_CARD_NUMBER: 141 group = CREDIT_CARD_NUMBER; 142 break; 143 case ::autofill::CREDIT_CARD_TYPE: 144 group = CREDIT_CARD_TYPE; 145 break; 146 default: 147 group = CREDIT_CARD_DATE; 148 } 149 break; 150 151 default: 152 NOTREACHED(); 153 group = AMBIGUOUS; 154 } 155 156 // Interpolate the |metric| with the |group|, so that all metrics for a given 157 // |group| are adjacent. 158 return (group * num_possible_metrics) + metric; 159} 160 161// Returns the histogram prefix to use for reporting metrics for |dialog_type|. 162std::string GetPrefixForDialogType(autofill::DialogType dialog_type) { 163 switch (dialog_type) { 164 case autofill::DIALOG_TYPE_AUTOCHECKOUT: 165 return "Autocheckout"; 166 167 case autofill::DIALOG_TYPE_REQUEST_AUTOCOMPLETE: 168 return "RequestAutocomplete"; 169 } 170 171 NOTREACHED(); 172 return "UnknownDialogType"; 173} 174 175std::string WalletApiMetricToString( 176 AutofillMetrics::WalletApiCallMetric metric) { 177 switch (metric) { 178 case AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS: 179 return "AcceptLegalDocuments"; 180 case AutofillMetrics::AUTHENTICATE_INSTRUMENT: 181 return "AuthenticateInstrument"; 182 case AutofillMetrics::GET_FULL_WALLET: 183 return "GetFullWallet"; 184 case AutofillMetrics::GET_WALLET_ITEMS: 185 return "GetWalletItems"; 186 case AutofillMetrics::SAVE_TO_WALLET: 187 return "SaveToWallet"; 188 case AutofillMetrics::SEND_STATUS: 189 return "SendStatus"; 190 case AutofillMetrics::UNKNOWN_API_CALL: 191 NOTREACHED(); 192 return "UnknownApiCall"; 193 } 194 195 NOTREACHED(); 196 return "UnknownApiCall"; 197} 198 199// A version of the UMA_HISTOGRAM_ENUMERATION macro that allows the |name| 200// to vary over the program's runtime. 201void LogUMAHistogramEnumeration(const std::string& name, 202 int sample, 203 int boundary_value) { 204 DCHECK_LT(sample, boundary_value); 205 206 // Note: This leaks memory, which is expected behavior. 207 base::HistogramBase* histogram = 208 base::LinearHistogram::FactoryGet( 209 name, 210 1, 211 boundary_value, 212 boundary_value + 1, 213 base::HistogramBase::kUmaTargetedHistogramFlag); 214 histogram->Add(sample); 215} 216 217// A version of the UMA_HISTOGRAM_TIMES macro that allows the |name| 218// to vary over the program's runtime. 219void LogUMAHistogramTimes(const std::string& name, 220 const base::TimeDelta& duration) { 221 // Note: This leaks memory, which is expected behavior. 222 base::HistogramBase* histogram = 223 base::Histogram::FactoryTimeGet( 224 name, 225 base::TimeDelta::FromMilliseconds(1), 226 base::TimeDelta::FromSeconds(10), 227 50, 228 base::HistogramBase::kUmaTargetedHistogramFlag); 229 histogram->AddTime(duration); 230} 231 232// A version of the UMA_HISTOGRAM_LONG_TIMES macro that allows the |name| 233// to vary over the program's runtime. 234void LogUMAHistogramLongTimes(const std::string& name, 235 const base::TimeDelta& duration) { 236 // Note: This leaks memory, which is expected behavior. 237 base::HistogramBase* histogram = 238 base::Histogram::FactoryTimeGet( 239 name, 240 base::TimeDelta::FromMilliseconds(1), 241 base::TimeDelta::FromHours(1), 242 50, 243 base::HistogramBase::kUmaTargetedHistogramFlag); 244 histogram->AddTime(duration); 245} 246 247// Logs a type quality metric. The primary histogram name is constructed based 248// on |base_name| and |experiment_id|. The field-specific histogram name also 249// factors in the |field_type|. Logs a sample of |metric|, which should be in 250// the range [0, |num_possible_metrics|). 251void LogTypeQualityMetric(const std::string& base_name, 252 const int metric, 253 const int num_possible_metrics, 254 const ServerFieldType field_type, 255 const std::string& experiment_id) { 256 DCHECK_LT(metric, num_possible_metrics); 257 258 std::string histogram_name = base_name; 259 if (!experiment_id.empty()) 260 histogram_name += "_" + experiment_id; 261 LogUMAHistogramEnumeration(histogram_name, metric, num_possible_metrics); 262 263 std::string sub_histogram_name = base_name + ".ByFieldType"; 264 if (!experiment_id.empty()) 265 sub_histogram_name += "_" + experiment_id; 266 const int field_type_group_metric = 267 GetFieldTypeGroupMetric(field_type, metric, num_possible_metrics); 268 const int num_field_type_group_metrics = 269 num_possible_metrics * NUM_FIELD_TYPE_GROUPS_FOR_METRICS; 270 LogUMAHistogramEnumeration(sub_histogram_name, 271 field_type_group_metric, 272 num_field_type_group_metrics); 273} 274 275void LogServerExperimentId(const std::string& histogram_name, 276 const std::string& experiment_id) { 277 ServerExperiment metric = UNKNOWN_EXPERIMENT; 278 279 const std::string default_experiment_name = 280 FormStructure(FormData(), std::string()).server_experiment_id(); 281 if (experiment_id.empty()) 282 metric = NO_EXPERIMENT; 283 else if (experiment_id == "ar06") 284 metric = ACCEPTANCE_RATIO_06; 285 else if (experiment_id == "ar1") 286 metric = ACCEPTANCE_RATIO_1; 287 else if (experiment_id == "ar2") 288 metric = ACCEPTANCE_RATIO_2; 289 else if (experiment_id == "ar4") 290 metric = ACCEPTANCE_RATIO_4; 291 else if (experiment_id == "ar05wlr15") 292 metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15; 293 else if (experiment_id == "ar05wlr25") 294 metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_25; 295 else if (experiment_id == "ar05wr15fs5") 296 metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15_MIN_FORM_SCORE_5; 297 else if (experiment_id == "tbar1") 298 metric = TOOLBAR_DATA_ONLY; 299 else if (experiment_id == "ar04wr3fs4") 300 metric = ACCEPTANCE_RATIO_04_WINNER_LEAD_RATIO_3_MIN_FORM_SCORE_4; 301 else if (experiment_id == default_experiment_name) 302 metric = NO_SERVER_RESPONSE; 303 else if (experiment_id == "fp05") 304 metric = PROBABILITY_PICKER_05; 305 else if (experiment_id == "fp025") 306 metric = PROBABILITY_PICKER_025; 307 else if (experiment_id == "fp05cc03") 308 metric = PROBABILITY_PICKER_025_CC_THRESHOLD_03; 309 else if (experiment_id == "fp05cco03") 310 metric = PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03; 311 else if (experiment_id == "fp05cco03cstd") 312 metric = PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03_WITH_FALLBACK; 313 else if (experiment_id == "fp05cc03e1") 314 metric = PROBABILITY_PICKER_05_CC_NAME_THRESHOLD_03_EXPERIMENT_1; 315 316 DCHECK_LT(metric, NUM_SERVER_EXPERIMENTS); 317 LogUMAHistogramEnumeration(histogram_name, metric, NUM_SERVER_EXPERIMENTS); 318} 319 320} // namespace 321 322AutofillMetrics::AutofillMetrics() { 323} 324 325AutofillMetrics::~AutofillMetrics() { 326} 327 328void AutofillMetrics::LogAutocheckoutBubbleMetric(BubbleMetric metric) const { 329 DCHECK_LT(metric, NUM_BUBBLE_METRICS); 330 331 UMA_HISTOGRAM_ENUMERATION("Autocheckout.Bubble", metric, NUM_BUBBLE_METRICS); 332} 333 334void AutofillMetrics::LogAutocheckoutBuyFlowMetric( 335 AutocheckoutBuyFlowMetric metric) const { 336 DCHECK_LT(metric, NUM_AUTOCHECKOUT_BUY_FLOW_METRICS); 337 338 UMA_HISTOGRAM_ENUMERATION("Autocheckout.BuyFlow", metric, 339 NUM_AUTOCHECKOUT_BUY_FLOW_METRICS); 340} 341 342void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric) const { 343 DCHECK_LT(metric, NUM_INFO_BAR_METRICS); 344 345 UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar", metric, 346 NUM_INFO_BAR_METRICS); 347} 348 349void AutofillMetrics::LogDialogDismissalState( 350 autofill::DialogType dialog_type, 351 DialogDismissalState state) const { 352 std::string name = GetPrefixForDialogType(dialog_type) + ".DismissalState"; 353 LogUMAHistogramEnumeration(name, state, NUM_DIALOG_DISMISSAL_STATES); 354} 355 356void AutofillMetrics::LogDialogInitialUserState( 357 autofill::DialogType dialog_type, 358 DialogInitialUserStateMetric user_type) const { 359 std::string name = GetPrefixForDialogType(dialog_type) + ".InitialUserState"; 360 LogUMAHistogramEnumeration( 361 name, user_type, NUM_DIALOG_INITIAL_USER_STATE_METRICS); 362} 363 364void AutofillMetrics::LogDialogLatencyToShow( 365 autofill::DialogType dialog_type, 366 const base::TimeDelta& duration) const { 367 std::string name = 368 GetPrefixForDialogType(dialog_type) + ".UiLatencyToShow"; 369 LogUMAHistogramTimes(name, duration); 370} 371 372void AutofillMetrics::LogDialogPopupEvent(autofill::DialogType dialog_type, 373 DialogPopupEvent event) const { 374 std::string name = GetPrefixForDialogType(dialog_type) + ".PopupInDialog"; 375 LogUMAHistogramEnumeration(name, event, NUM_DIALOG_POPUP_EVENTS); 376} 377 378void AutofillMetrics::LogDialogSecurityMetric( 379 autofill::DialogType dialog_type, 380 DialogSecurityMetric metric) const { 381 std::string name = GetPrefixForDialogType(dialog_type) + ".Security"; 382 LogUMAHistogramEnumeration(name, metric, NUM_DIALOG_SECURITY_METRICS); 383} 384 385void AutofillMetrics::LogDialogUiDuration( 386 const base::TimeDelta& duration, 387 autofill::DialogType dialog_type, 388 DialogDismissalAction dismissal_action) const { 389 std::string prefix = GetPrefixForDialogType(dialog_type); 390 391 std::string suffix; 392 switch (dismissal_action) { 393 case DIALOG_ACCEPTED: 394 suffix = "Submit"; 395 break; 396 397 case DIALOG_CANCELED: 398 suffix = "Cancel"; 399 break; 400 } 401 402 LogUMAHistogramLongTimes(prefix + ".UiDuration", duration); 403 LogUMAHistogramLongTimes(prefix + ".UiDuration." + suffix, duration); 404} 405 406void AutofillMetrics::LogDialogUiEvent(autofill::DialogType dialog_type, 407 DialogUiEvent event) const { 408 std::string name = GetPrefixForDialogType(dialog_type) + ".UiEvents"; 409 LogUMAHistogramEnumeration(name, event, NUM_DIALOG_UI_EVENTS); 410} 411 412void AutofillMetrics::LogWalletErrorMetric(autofill::DialogType dialog_type, 413 WalletErrorMetric metric) const { 414 std::string name = GetPrefixForDialogType(dialog_type) + ".WalletErrors"; 415 LogUMAHistogramEnumeration(name, metric, NUM_WALLET_ERROR_METRICS); 416} 417 418void AutofillMetrics::LogWalletApiCallDuration( 419 WalletApiCallMetric metric, 420 const base::TimeDelta& duration) const { 421 LogUMAHistogramTimes("Wallet.ApiCallDuration." + 422 WalletApiMetricToString(metric), duration); 423} 424 425void AutofillMetrics::LogWalletRequiredActionMetric( 426 autofill::DialogType dialog_type, 427 WalletRequiredActionMetric required_action) const { 428 std::string name = 429 GetPrefixForDialogType(dialog_type) + ".WalletRequiredActions"; 430 LogUMAHistogramEnumeration( 431 name, required_action, NUM_WALLET_REQUIRED_ACTIONS); 432} 433 434void AutofillMetrics::LogAutocheckoutDuration( 435 const base::TimeDelta& duration, 436 AutocheckoutCompletionStatus status) const { 437 std::string suffix; 438 switch (status) { 439 case AUTOCHECKOUT_CANCELLED: 440 suffix = "Cancelled"; 441 break; 442 443 case AUTOCHECKOUT_FAILED: 444 suffix = "Failed"; 445 break; 446 447 case AUTOCHECKOUT_SUCCEEDED: 448 suffix = "Succeeded"; 449 break; 450 } 451 452 LogUMAHistogramLongTimes("Autocheckout.FlowDuration", duration); 453 LogUMAHistogramLongTimes("Autocheckout.FlowDuration." + suffix, duration); 454} 455 456void AutofillMetrics::LogAutocheckoutWhitelistDownloadDuration( 457 const base::TimeDelta& duration, 458 AutocheckoutWhitelistDownloadStatus status) const { 459 std::string suffix; 460 switch (status) { 461 case AUTOCHECKOUT_WHITELIST_DOWNLOAD_FAILED: 462 suffix = "Failed"; 463 break; 464 465 case AUTOCHECKOUT_WHITELIST_DOWNLOAD_SUCCEEDED: 466 suffix = "Succeeded"; 467 break; 468 } 469 470 LogUMAHistogramTimes("Autocheckout.WhitelistDownloadDuration", duration); 471 LogUMAHistogramTimes( 472 "Autocheckout.WhitelistDownloadDuration." + suffix, duration); 473} 474 475void AutofillMetrics::LogDeveloperEngagementMetric( 476 DeveloperEngagementMetric metric) const { 477 DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS); 478 479 UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric, 480 NUM_DEVELOPER_ENGAGEMENT_METRICS); 481} 482 483void AutofillMetrics::LogHeuristicTypePrediction( 484 FieldTypeQualityMetric metric, 485 ServerFieldType field_type, 486 const std::string& experiment_id) const { 487 LogTypeQualityMetric("Autofill.Quality.HeuristicType", 488 metric, NUM_FIELD_TYPE_QUALITY_METRICS, 489 field_type, experiment_id); 490} 491 492void AutofillMetrics::LogOverallTypePrediction( 493 FieldTypeQualityMetric metric, 494 ServerFieldType field_type, 495 const std::string& experiment_id) const { 496 LogTypeQualityMetric("Autofill.Quality.PredictedType", 497 metric, NUM_FIELD_TYPE_QUALITY_METRICS, 498 field_type, experiment_id); 499} 500 501void AutofillMetrics::LogServerTypePrediction( 502 FieldTypeQualityMetric metric, 503 ServerFieldType field_type, 504 const std::string& experiment_id) const { 505 LogTypeQualityMetric("Autofill.Quality.ServerType", 506 metric, NUM_FIELD_TYPE_QUALITY_METRICS, 507 field_type, experiment_id); 508} 509 510void AutofillMetrics::LogQualityMetric(QualityMetric metric, 511 const std::string& experiment_id) const { 512 DCHECK_LT(metric, NUM_QUALITY_METRICS); 513 514 std::string histogram_name = "Autofill.Quality"; 515 if (!experiment_id.empty()) 516 histogram_name += "_" + experiment_id; 517 518 LogUMAHistogramEnumeration(histogram_name, metric, NUM_QUALITY_METRICS); 519} 520 521void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) const { 522 DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS); 523 524 UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric, 525 NUM_SERVER_QUERY_METRICS); 526} 527 528void AutofillMetrics::LogUserHappinessMetric(UserHappinessMetric metric) const { 529 DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS); 530 531 UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric, 532 NUM_USER_HAPPINESS_METRICS); 533} 534 535void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill( 536 const base::TimeDelta& duration) const { 537 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithAutofill", 538 duration, 539 base::TimeDelta::FromMilliseconds(100), 540 base::TimeDelta::FromMinutes(10), 541 50); 542} 543 544void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill( 545 const base::TimeDelta& duration) const { 546 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithoutAutofill", 547 duration, 548 base::TimeDelta::FromMilliseconds(100), 549 base::TimeDelta::FromMinutes(10), 550 50); 551} 552 553void AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill( 554 const base::TimeDelta& duration) const { 555 UMA_HISTOGRAM_CUSTOM_TIMES( 556 "Autofill.FillDuration.FromInteraction.WithAutofill", 557 duration, 558 base::TimeDelta::FromMilliseconds(100), 559 base::TimeDelta::FromMinutes(10), 560 50); 561} 562 563void AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill( 564 const base::TimeDelta& duration) const { 565 UMA_HISTOGRAM_CUSTOM_TIMES( 566 "Autofill.FillDuration.FromInteraction.WithoutAutofill", 567 duration, 568 base::TimeDelta::FromMilliseconds(100), 569 base::TimeDelta::FromMinutes(10), 570 50); 571} 572 573void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) const { 574 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled); 575} 576 577void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled) const { 578 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled); 579} 580 581void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) const { 582 UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles); 583} 584 585void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) const { 586 UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions); 587} 588 589void AutofillMetrics::LogServerExperimentIdForQuery( 590 const std::string& experiment_id) const { 591 LogServerExperimentId("Autofill.ServerExperimentId.Query", experiment_id); 592} 593 594void AutofillMetrics::LogServerExperimentIdForUpload( 595 const std::string& experiment_id) const { 596 LogServerExperimentId("Autofill.ServerExperimentId.Upload", experiment_id); 597} 598 599} // namespace autofill 600