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

Side by Side Diff: components/autofill/core/browser/autofill_metrics.cc

Issue 2940983003: [autofill] Add UKM for field type prediction quality and autofill outcome. (Closed)
Patch Set: fix a comment Created 3 years, 5 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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/autofill/core/browser/autofill_metrics.h" 5 #include "components/autofill/core/browser/autofill_metrics.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/metrics/sparse_histogram.h" 13 #include "base/metrics/sparse_histogram.h"
14 #include "base/metrics/user_metrics.h" 14 #include "base/metrics/user_metrics.h"
15 #include "base/strings/string_piece.h" 15 #include "base/strings/string_piece.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "components/autofill/core/browser/autofill_experiments.h" 18 #include "components/autofill/core/browser/autofill_experiments.h"
19 #include "components/autofill/core/browser/autofill_field.h" 19 #include "components/autofill/core/browser/autofill_field.h"
20 #include "components/autofill/core/browser/autofill_type.h" 20 #include "components/autofill/core/browser/autofill_type.h"
21 #include "components/autofill/core/browser/form_structure.h" 21 #include "components/autofill/core/browser/form_structure.h"
22 #include "components/autofill/core/common/autofill_clock.h"
22 #include "components/autofill/core/common/form_data.h" 23 #include "components/autofill/core/common/form_data.h"
23 #include "components/ukm/public/ukm_entry_builder.h" 24 #include "components/ukm/public/ukm_entry_builder.h"
24 25
25 namespace internal { 26 namespace internal {
26 const char kUKMCardUploadDecisionEntryName[] = "Autofill.CardUploadDecision"; 27 const char kUKMCardUploadDecisionEntryName[] = "Autofill.CardUploadDecision";
27 const char kUKMCardUploadDecisionMetricName[] = "UploadDecision"; 28 const char kUKMCardUploadDecisionMetricName[] = "UploadDecision";
28 const char kUKMDeveloperEngagementEntryName[] = "Autofill.DeveloperEngagement"; 29 const char kUKMDeveloperEngagementEntryName[] = "Autofill.DeveloperEngagement";
29 const char kUKMDeveloperEngagementMetricName[] = "DeveloperEngagement"; 30 const char kUKMDeveloperEngagementMetricName[] = "DeveloperEngagement";
30 const char kUKMMillisecondsSinceFormParsedMetricName[] = 31 const char kUKMMillisecondsSinceFormParsedMetricName[] =
31 "MillisecondsSinceFormParsed"; 32 "MillisecondsSinceFormParsed";
(...skipping 10 matching lines...) Expand all
42 const char kUKMFieldTypeGroupMetricName[] = "FieldTypeGroup"; 43 const char kUKMFieldTypeGroupMetricName[] = "FieldTypeGroup";
43 const char kUKMHeuristicTypeMetricName[] = "HeuristicType"; 44 const char kUKMHeuristicTypeMetricName[] = "HeuristicType";
44 const char kUKMServerTypeMetricName[] = "ServerType"; 45 const char kUKMServerTypeMetricName[] = "ServerType";
45 const char kUKMHtmlFieldTypeMetricName[] = "HtmlFieldType"; 46 const char kUKMHtmlFieldTypeMetricName[] = "HtmlFieldType";
46 const char kUKMHtmlFieldModeMetricName[] = "HtmlFieldMode"; 47 const char kUKMHtmlFieldModeMetricName[] = "HtmlFieldMode";
47 const char kUKMIsAutofilledMetricName[] = "IsAutofilled"; 48 const char kUKMIsAutofilledMetricName[] = "IsAutofilled";
48 const char kUKMIsEmptyMetricName[] = "IsEmpty"; 49 const char kUKMIsEmptyMetricName[] = "IsEmpty";
49 const char kUKMFormSubmittedEntryName[] = "Autofill.AutofillFormSubmitted"; 50 const char kUKMFormSubmittedEntryName[] = "Autofill.AutofillFormSubmitted";
50 const char kUKMAutofillFormSubmittedStateMetricName[] = 51 const char kUKMAutofillFormSubmittedStateMetricName[] =
51 "AutofillFormSubmittedState"; 52 "AutofillFormSubmittedState";
53 // |UkmEntry| for capturing field type prediction quality.
54 const char kUKMFieldTypeEntryName[] = "Autofill.FieldTypeValidation";
55 const char kUKMFieldFillStatusEntryName[] = "Autofill.FieldFillStatus";
56 const char kUKMFormSignatureMetricName[] = "FormSignature";
57 const char kUKMFieldSignatureMetricName[] = "FieldSignature";
58 const char kUKMValidationEventMetricName[] = "ValidationEvent";
59 const char kUKMPredictionSourceMetricName[] = "PredictionSource";
60 const char kUKMPredictedTypeMetricName[] = "PredictedType";
61 const char kUKMActualTypeMetricName[] = "ActualType";
62 const char kUKMWasSuggestionShownMetricName[] = "WasSuggestionShown";
63 const char kUKMWasPreviouslyAutofilledMetricName[] = "WasPreviouslyAutofilled";
64
52 } // namespace internal 65 } // namespace internal
53 66
54 namespace autofill { 67 namespace autofill {
55 68
56 namespace { 69 namespace {
57 70
58 // Note: if adding an enum value here, update the corresponding description for 71 // Note: if adding an enum value here, update the corresponding description for
59 // AutofillTypeQualityByFieldType in histograms.xml. 72 // AutofillTypeQualityByFieldType in histograms.xml.
60 enum FieldTypeGroupForMetrics { 73 enum FieldTypeGroupForMetrics {
61 GROUP_AMBIGUOUS = 0, 74 GROUP_AMBIGUOUS = 0,
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 base::HistogramBase* histogram = 283 base::HistogramBase* histogram =
271 base::Histogram::FactoryTimeGet( 284 base::Histogram::FactoryTimeGet(
272 name, 285 name,
273 base::TimeDelta::FromMilliseconds(1), 286 base::TimeDelta::FromMilliseconds(1),
274 base::TimeDelta::FromHours(1), 287 base::TimeDelta::FromHours(1),
275 50, 288 50,
276 base::HistogramBase::kUmaTargetedHistogramFlag); 289 base::HistogramBase::kUmaTargetedHistogramFlag);
277 histogram->AddTime(duration); 290 histogram->AddTime(duration);
278 } 291 }
279 292
293 const char* GetQualityMetricPredictionSource(
294 AutofillMetrics::QualityMetricPredictionSource source) {
295 switch (source) {
296 default:
297 case AutofillMetrics::PREDICTION_SOURCE_UNKNOWN:
298 NOTREACHED();
299 return "Unknown";
300
301 case AutofillMetrics::PREDICTION_SOURCE_HEURISTIC:
302 return "Heuristic";
303 case AutofillMetrics::PREDICTION_SOURCE_SERVER:
304 return "Server";
305 case AutofillMetrics::PREDICTION_SOURCE_OVERALL:
306 return "Overall";
307 }
308 }
309
280 const char* GetQualityMetricTypeSuffix( 310 const char* GetQualityMetricTypeSuffix(
281 AutofillMetrics::QualityMetricType metric_type) { 311 AutofillMetrics::QualityMetricType metric_type) {
282 switch (metric_type) { 312 switch (metric_type) {
283 default: 313 default:
284 NOTREACHED(); 314 NOTREACHED();
285 // Fall through... 315 // Fall through...
286 316
287 case AutofillMetrics::TYPE_SUBMISSION: 317 case AutofillMetrics::TYPE_SUBMISSION:
288 return ""; 318 return "";
289 case AutofillMetrics::TYPE_NO_SUBMISSION: 319 case AutofillMetrics::TYPE_NO_SUBMISSION:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 // Capture the field's type, if it is unambiguous. 362 // Capture the field's type, if it is unambiguous.
333 ServerFieldType actual_type = AMBIGUOUS_TYPE; 363 ServerFieldType actual_type = AMBIGUOUS_TYPE;
334 if (collapsed_field_types.size() == 1) 364 if (collapsed_field_types.size() == 1)
335 actual_type = *collapsed_field_types.begin(); 365 actual_type = *collapsed_field_types.begin();
336 366
337 DVLOG(2) << "Inferred Type: " << AutofillType(actual_type).ToString(); 367 DVLOG(2) << "Inferred Type: " << AutofillType(actual_type).ToString();
338 return actual_type; 368 return actual_type;
339 } 369 }
340 370
341 // Logs field type prediction quality metrics. The primary histogram name is 371 // Logs field type prediction quality metrics. The primary histogram name is
342 // constructed based on |source| The field-specific histogram name also factors 372 // constructed based on |prediction_source| The field-specific histogram names
343 // possible and predicted field types (|possible_types| and |predicted_type|, 373 // also incorporates the possible and predicted types for |field|. A suffix may
344 // respectively). May log a suffixed version of the metric depending on 374 // be appended to the metric name, depending on |metric_type|.
345 // |metric_type|.
346 void LogPredictionQualityMetrics( 375 void LogPredictionQualityMetrics(
347 const base::StringPiece& source, 376 AutofillMetrics::QualityMetricPredictionSource prediction_source,
348 const ServerFieldTypeSet& possible_types,
349 ServerFieldType predicted_type, 377 ServerFieldType predicted_type,
378 AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
379 const FormStructure& form,
380 const AutofillField& field,
350 AutofillMetrics::QualityMetricType metric_type) { 381 AutofillMetrics::QualityMetricType metric_type) {
351 // Generate histogram names. 382 // Generate histogram names.
352 const char* const suffix = GetQualityMetricTypeSuffix(metric_type); 383 const char* source = GetQualityMetricPredictionSource(prediction_source);
384 const char* suffix = GetQualityMetricTypeSuffix(metric_type);
353 std::string raw_data_histogram = 385 std::string raw_data_histogram =
354 base::JoinString({"Autofill.FieldPrediction.", source, suffix}, ""); 386 base::JoinString({"Autofill.FieldPrediction.", source, suffix}, "");
355 std::string aggregate_histogram = base::JoinString( 387 std::string aggregate_histogram = base::JoinString(
356 {"Autofill.FieldPredictionQuality.Aggregate.", source, suffix}, ""); 388 {"Autofill.FieldPredictionQuality.Aggregate.", source, suffix}, "");
357 std::string type_specific_histogram = base::JoinString( 389 std::string type_specific_histogram = base::JoinString(
358 {"Autofill.FieldPredictionQuality.ByFieldType.", source, suffix}, ""); 390 {"Autofill.FieldPredictionQuality.ByFieldType.", source, suffix}, "");
359 391
392 const ServerFieldTypeSet& possible_types =
393 metric_type == AutofillMetrics::TYPE_AUTOCOMPLETE_BASED
394 ? ServerFieldTypeSet{AutofillType(field.html_type(),
395 field.html_mode())
396 .GetStorableType()}
397 : field.possible_types();
398
360 // Get the best type classification we can for the field. 399 // Get the best type classification we can for the field.
361 ServerFieldType actual_type = 400 ServerFieldType actual_type =
362 GetActualFieldType(possible_types, predicted_type); 401 GetActualFieldType(possible_types, predicted_type);
363 402
364 DVLOG(2) << "Predicted: " << AutofillType(predicted_type).ToString() << "; " 403 DVLOG(2) << "Predicted: " << AutofillType(predicted_type).ToString() << "; "
365 << "Actual: " << AutofillType(actual_type).ToString(); 404 << "Actual: " << AutofillType(actual_type).ToString();
366 405
367 DCHECK_LE(predicted_type, UINT16_MAX); 406 DCHECK_LE(predicted_type, UINT16_MAX);
368 DCHECK_LE(actual_type, UINT16_MAX); 407 DCHECK_LE(actual_type, UINT16_MAX);
369 UMA_HISTOGRAM_SPARSE_SLOWLY(raw_data_histogram, 408 UMA_HISTOGRAM_SPARSE_SLOWLY(raw_data_histogram,
370 (predicted_type << 16) | actual_type); 409 (predicted_type << 16) | actual_type);
371 410
411 form_interactions_ukm_logger->LogFieldType(
412 form.form_signature(), field.GetFieldSignature(), prediction_source,
413 metric_type, predicted_type, actual_type);
414
372 // NO_SERVER_DATA is the equivalent of predicting UNKNOWN. 415 // NO_SERVER_DATA is the equivalent of predicting UNKNOWN.
373 if (predicted_type == NO_SERVER_DATA) 416 if (predicted_type == NO_SERVER_DATA)
374 predicted_type = UNKNOWN_TYPE; 417 predicted_type = UNKNOWN_TYPE;
375 418
376 // The actual type being EMPTY_TYPE is the same as UNKNOWN_TYPE for comparison 419 // The actual type being EMPTY_TYPE is the same as UNKNOWN_TYPE for comparison
377 // purposes, but remember whether or not it was empty for more precise logging 420 // purposes, but remember whether or not it was empty for more precise logging
378 // later. 421 // later.
379 bool is_empty = (actual_type == EMPTY_TYPE); 422 bool is_empty = (actual_type == EMPTY_TYPE);
380 bool is_ambiguous = (actual_type == AMBIGUOUS_TYPE); 423 bool is_ambiguous = (actual_type == AMBIGUOUS_TYPE);
381 if (is_empty || is_ambiguous) 424 if (is_empty || is_ambiguous)
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 700
658 // static 701 // static
659 void AutofillMetrics::LogDeveloperEngagementMetric( 702 void AutofillMetrics::LogDeveloperEngagementMetric(
660 DeveloperEngagementMetric metric) { 703 DeveloperEngagementMetric metric) {
661 DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS); 704 DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS);
662 UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric, 705 UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric,
663 NUM_DEVELOPER_ENGAGEMENT_METRICS); 706 NUM_DEVELOPER_ENGAGEMENT_METRICS);
664 } 707 }
665 708
666 void AutofillMetrics::LogHeuristicPredictionQualityMetrics( 709 void AutofillMetrics::LogHeuristicPredictionQualityMetrics(
667 const ServerFieldTypeSet& possible_types, 710 FormInteractionsUkmLogger* form_interactions_ukm_logger,
668 ServerFieldType predicted_type, 711 const FormStructure& form,
669 AutofillMetrics::QualityMetricType metric_type) { 712 const AutofillField& field,
670 LogPredictionQualityMetrics("Heuristic", possible_types, predicted_type, 713 QualityMetricType metric_type) {
671 metric_type); 714 LogPredictionQualityMetrics(
715 PREDICTION_SOURCE_HEURISTIC,
716 AutofillType(field.heuristic_type()).GetStorableType(),
717 form_interactions_ukm_logger, form, field, metric_type);
672 } 718 }
673 719
674 void AutofillMetrics::LogServerPredictionQualityMetrics( 720 void AutofillMetrics::LogServerPredictionQualityMetrics(
675 const ServerFieldTypeSet& possible_types, 721 FormInteractionsUkmLogger* form_interactions_ukm_logger,
676 ServerFieldType predicted_type, 722 const FormStructure& form,
677 AutofillMetrics::QualityMetricType metric_type) { 723 const AutofillField& field,
678 LogPredictionQualityMetrics("Server", possible_types, predicted_type, 724 QualityMetricType metric_type) {
679 metric_type); 725 LogPredictionQualityMetrics(
726 PREDICTION_SOURCE_SERVER,
727 AutofillType(field.server_type()).GetStorableType(),
728 form_interactions_ukm_logger, form, field, metric_type);
680 } 729 }
681 730
682 void AutofillMetrics::LogOverallPredictionQualityMetrics( 731 void AutofillMetrics::LogOverallPredictionQualityMetrics(
683 const ServerFieldTypeSet& possible_types, 732 FormInteractionsUkmLogger* form_interactions_ukm_logger,
684 ServerFieldType predicted_type, 733 const FormStructure& form,
685 AutofillMetrics::QualityMetricType metric_type) { 734 const AutofillField& field,
686 LogPredictionQualityMetrics("Overall", possible_types, predicted_type, 735 QualityMetricType metric_type) {
687 metric_type); 736 LogPredictionQualityMetrics(
737 PREDICTION_SOURCE_OVERALL, field.Type().GetStorableType(),
738 form_interactions_ukm_logger, form, field, metric_type);
688 } 739 }
689 740
690 // static 741 // static
691 void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) { 742 void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) {
692 DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS); 743 DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS);
693 UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric, 744 UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
694 NUM_SERVER_QUERY_METRICS); 745 NUM_SERVER_QUERY_METRICS);
695 } 746 }
696 747
697 // static 748 // static
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 builder->AddMetric(internal::kUKMHtmlFieldTypeMetricName, 1368 builder->AddMetric(internal::kUKMHtmlFieldTypeMetricName,
1318 static_cast<int>(field.html_type())); 1369 static_cast<int>(field.html_type()));
1319 builder->AddMetric(internal::kUKMHtmlFieldModeMetricName, 1370 builder->AddMetric(internal::kUKMHtmlFieldModeMetricName,
1320 static_cast<int>(field.html_mode())); 1371 static_cast<int>(field.html_mode()));
1321 builder->AddMetric(internal::kUKMIsAutofilledMetricName, field.is_autofilled); 1372 builder->AddMetric(internal::kUKMIsAutofilledMetricName, field.is_autofilled);
1322 builder->AddMetric(internal::kUKMIsEmptyMetricName, field.IsEmpty()); 1373 builder->AddMetric(internal::kUKMIsEmptyMetricName, field.IsEmpty());
1323 builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName, 1374 builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
1324 MillisecondsSinceFormParsed()); 1375 MillisecondsSinceFormParsed());
1325 } 1376 }
1326 1377
1378 void AutofillMetrics::FormInteractionsUkmLogger::LogFieldFillStatus(
1379 const FormStructure& form,
1380 const AutofillField& field,
1381 QualityMetricType metric_type) {
1382 if (!CanLog())
1383 return;
1384
1385 if (source_id_ == -1)
1386 GetNewSourceID();
1387
1388 std::unique_ptr<ukm::UkmEntryBuilder> builder =
1389 ukm_recorder_->GetEntryBuilder(source_id_,
1390 internal::kUKMFieldFillStatusEntryName);
1391 builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
1392 MillisecondsSinceFormParsed());
1393 builder->AddMetric(internal::kUKMFormSignatureMetricName,
1394 static_cast<int64_t>(form.form_signature()));
1395 builder->AddMetric(internal::kUKMFieldSignatureMetricName,
1396 static_cast<int64_t>(field.GetFieldSignature()));
1397 builder->AddMetric(internal::kUKMValidationEventMetricName,
1398 static_cast<int64_t>(metric_type));
1399 builder->AddMetric(internal::kUKMIsAutofilledMetricName,
1400 static_cast<int64_t>(field.is_autofilled));
1401 builder->AddMetric(internal::kUKMWasPreviouslyAutofilledMetricName,
1402 static_cast<int64_t>(field.previously_autofilled()));
1403 }
1404
1405 void AutofillMetrics::FormInteractionsUkmLogger::LogFieldType(
1406 FormSignature form_signature,
1407 FieldSignature field_signature,
1408 QualityMetricPredictionSource prediction_source,
1409 QualityMetricType metric_type,
1410 ServerFieldType predicted_type,
1411 ServerFieldType actual_type) {
1412 if (!CanLog())
1413 return;
1414
1415 if (source_id_ == -1)
1416 GetNewSourceID();
1417
1418 std::unique_ptr<ukm::UkmEntryBuilder> builder =
1419 ukm_recorder_->GetEntryBuilder(source_id_,
1420 internal::kUKMFieldTypeEntryName);
1421 builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName,
1422 MillisecondsSinceFormParsed());
1423 builder->AddMetric(internal::kUKMFormSignatureMetricName,
1424 static_cast<int64_t>(form_signature));
1425 builder->AddMetric(internal::kUKMFieldSignatureMetricName,
1426 static_cast<int64_t>(field_signature));
1427 builder->AddMetric(internal::kUKMValidationEventMetricName,
1428 static_cast<int64_t>(metric_type));
1429 builder->AddMetric(internal::kUKMPredictionSourceMetricName,
1430 static_cast<int64_t>(prediction_source));
1431 builder->AddMetric(internal::kUKMPredictedTypeMetricName,
1432 static_cast<int64_t>(predicted_type));
1433 builder->AddMetric(internal::kUKMActualTypeMetricName,
1434 static_cast<int64_t>(actual_type));
1435 }
1436
1327 void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted( 1437 void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
1328 AutofillFormSubmittedState state) { 1438 AutofillFormSubmittedState state) {
1329 if (!CanLog()) 1439 if (!CanLog())
1330 return; 1440 return;
1331 1441
1332 if (source_id_ == -1) 1442 if (source_id_ == -1)
1333 GetNewSourceID(); 1443 GetNewSourceID();
1334 1444
1335 std::unique_ptr<ukm::UkmEntryBuilder> builder = 1445 std::unique_ptr<ukm::UkmEntryBuilder> builder =
1336 ukm_recorder_->GetEntryBuilder(source_id_, 1446 ukm_recorder_->GetEntryBuilder(source_id_,
(...skipping 17 matching lines...) Expand all
1354 } 1464 }
1355 1465
1356 bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const { 1466 bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const {
1357 return ukm_recorder_ && url_.is_valid(); 1467 return ukm_recorder_ && url_.is_valid();
1358 } 1468 }
1359 1469
1360 int64_t 1470 int64_t
1361 AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed() 1471 AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed()
1362 const { 1472 const {
1363 DCHECK(!form_parsed_timestamp_.is_null()); 1473 DCHECK(!form_parsed_timestamp_.is_null());
1364 return (base::TimeTicks::Now() - form_parsed_timestamp_).InMilliseconds(); 1474 // Use the pinned timestamp as the current time if it's set.
1475 base::TimeTicks now =
1476 pinned_timestamp_.is_null() ? base::TimeTicks::Now() : pinned_timestamp_;
1477 return (now - form_parsed_timestamp_).InMilliseconds();
1365 } 1478 }
1366 1479
1367 void AutofillMetrics::FormInteractionsUkmLogger::GetNewSourceID() { 1480 void AutofillMetrics::FormInteractionsUkmLogger::GetNewSourceID() {
1368 source_id_ = ukm_recorder_->GetNewSourceID(); 1481 source_id_ = ukm_recorder_->GetNewSourceID();
1369 ukm_recorder_->UpdateSourceURL(source_id_, url_); 1482 ukm_recorder_->UpdateSourceURL(source_id_, url_);
1370 } 1483 }
1371 1484
1485 AutofillMetrics::UkmTimestampPin::UkmTimestampPin(
1486 FormInteractionsUkmLogger* logger)
1487 : logger_(logger) {
1488 DCHECK(logger_);
1489 DCHECK(!logger_->has_pinned_timestamp());
1490 logger_->set_pinned_timestamp(base::TimeTicks::Now());
1491 }
1492
1493 AutofillMetrics::UkmTimestampPin::~UkmTimestampPin() {
1494 DCHECK(logger_->has_pinned_timestamp());
1495 logger_->set_pinned_timestamp(base::TimeTicks());
1496 }
1497
1372 } // namespace autofill 1498 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/autofill_metrics.h ('k') | components/autofill/core/browser/autofill_metrics_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698