summaryrefslogtreecommitdiff
path: root/chromium/components/autofill
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-16 09:59:13 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-20 10:28:53 +0000
commit6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch)
treec8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/components/autofill
parent3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff)
downloadqtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811 Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/autofill')
-rw-r--r--chromium/components/autofill/OWNERS1
-rw-r--r--chromium/components/autofill/android/BUILD.gn16
-rw-r--r--chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java17
-rw-r--r--chromium/components/autofill/android/java/strings/autofill_strings.grd11
-rw-r--r--chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc3
-rw-r--r--chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc1
-rw-r--r--chromium/components/autofill/content/renderer/form_autofill_util.cc20
-rw-r--r--chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc2
-rw-r--r--chromium/components/autofill/content/renderer/form_tracker.cc20
-rw-r--r--chromium/components/autofill/content/renderer/form_tracker.h5
-rw-r--r--chromium/components/autofill/content/renderer/page_form_analyser_logger.cc30
-rw-r--r--chromium/components/autofill/content/renderer/page_passwords_analyser.cc2
-rw-r--r--chromium/components/autofill/content/renderer/password_autofill_agent.cc9
-rw-r--r--chromium/components/autofill/content/renderer/password_autofill_agent.h4
-rw-r--r--chromium/components/autofill/content/renderer/password_generation_agent.cc11
-rw-r--r--chromium/components/autofill/content/renderer/prefilled_values_detector.cc2
-rw-r--r--chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc5
-rw-r--r--chromium/components/autofill/core/browser/BUILD.gn34
-rw-r--r--chromium/components/autofill/core/browser/DEPS1
-rw-r--r--chromium/components/autofill/core/browser/OWNERS1
-rw-r--r--chromium/components/autofill/core/browser/accessory_sheet_data.cc5
-rw-r--r--chromium/components/autofill/core/browser/accessory_sheet_data.h16
-rw-r--r--chromium/components/autofill/core/browser/account_info_getter.h2
-rw-r--r--chromium/components/autofill/core/browser/address_form_label_formatter.cc31
-rw-r--r--chromium/components/autofill/core/browser/address_form_label_formatter.h39
-rw-r--r--chromium/components/autofill/core/browser/address_i18n_unittest.cc24
-rw-r--r--chromium/components/autofill/core/browser/autocomplete_history_manager.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_assistant.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_client.h63
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model.cc16
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model.h32
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model_unittest.cc43
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_util_unittest.cc8
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager.cc167
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager.h23
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc335
-rw-r--r--chromium/components/autofill/core/browser/autofill_driver_factory.h2
-rw-r--r--chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_experiments.cc3
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate.cc20
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc42
-rw-r--r--chromium/components/autofill/core/browser/autofill_field.cc13
-rw-r--r--chromium/components/autofill/core/browser/autofill_field.h15
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.cc87
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.h17
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager_unittest.cc121
-rw-r--r--chromium/components/autofill/core/browser/autofill_merge_unittest.cc4
-rw-r--r--chromium/components/autofill/core/browser/autofill_metadata.h4
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.cc486
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.h253
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics_unittest.cc1531
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.cc61
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.h45
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_sync_util.cc235
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_sync_util.h20
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc8
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_unittest.cc653
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validation_util.cc196
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc834
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validator.cc14
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validator.h18
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc176
-rw-r--r--chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc15
-rw-r--r--chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h8
-rw-r--r--chromium/components/autofill/core/browser/autofill_scanner.h2
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.cc2
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.h2
-rw-r--r--chromium/components/autofill/core/browser/autofill_type.cc3
-rw-r--r--chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc13
-rw-r--r--chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h11
-rw-r--r--chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc52
-rw-r--r--chromium/components/autofill/core/browser/contact_form_label_formatter.cc36
-rw-r--r--chromium/components/autofill/core/browser/contact_form_label_formatter.h49
-rw-r--r--chromium/components/autofill/core/browser/contact_info_unittest.cc8
-rw-r--r--chromium/components/autofill/core/browser/credit_card.cc31
-rw-r--r--chromium/components/autofill/core/browser/credit_card.h2
-rw-r--r--chromium/components/autofill/core/browser/credit_card_field.cc2
-rw-r--r--chromium/components/autofill/core/browser/credit_card_field_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_manager.cc129
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_manager.h55
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc344
-rw-r--r--chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc138
-rw-r--r--chromium/components/autofill/core/browser/credit_card_unittest.cc160
-rw-r--r--chromium/components/autofill/core/browser/field_filler.cc4
-rw-r--r--chromium/components/autofill/core/browser/field_filler_unittest.cc111
-rw-r--r--chromium/components/autofill/core/browser/field_types.h5
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer.cc13
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer.h5
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/form_field.cc22
-rw-r--r--chromium/components/autofill/core/browser/form_field.h2
-rw-r--r--chromium/components/autofill/core/browser/form_structure.cc1
-rw-r--r--chromium/components/autofill/core/browser/form_structure.h4
-rw-r--r--chromium/components/autofill/core/browser/label_formatter.cc17
-rw-r--r--chromium/components/autofill/core/browser/label_formatter.h53
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils.cc115
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils.h58
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc100
-rw-r--r--chromium/components/autofill/core/browser/legacy_strike_database.cc1
-rw-r--r--chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/legal_message_line_unittest.cc6
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_manager.cc156
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_manager.h32
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc325
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_strike_database.cc7
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_strike_database.h10
-rw-r--r--chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc111
-rw-r--r--chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc91
-rw-r--r--chromium/components/autofill/core/browser/metrics/address_form_event_logger.h45
-rw-r--r--chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc194
-rw-r--r--chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h91
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc199
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_event_logger_base.h107
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_events.h97
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc1
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.cc31
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.h5
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client_unittest.cc49
-rw-r--r--chromium/components/autofill/core/browser/payments/test_payments_client.cc18
-rw-r--r--chromium/components/autofill/core/browser/payments/test_payments_client.h7
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.cc276
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.h85
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager_unittest.cc1089
-rw-r--r--chromium/components/autofill/core/browser/phone_number_i18n.cc11
-rw-r--r--chromium/components/autofill/core/browser/phone_number_i18n.h10
-rw-r--r--chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc37
-rw-r--r--chromium/components/autofill/core/browser/price_field.cc34
-rw-r--r--chromium/components/autofill/core/browser/price_field.h40
-rw-r--r--chromium/components/autofill/core/browser/price_field_unittest.cc78
-rw-r--r--chromium/components/autofill/core/browser/proto/server.proto8
-rw-r--r--chromium/components/autofill/core/browser/randomized_encoder_unittest.cc12
-rw-r--r--chromium/components/autofill/core/browser/region_data_loader_impl.cc1
-rw-r--r--chromium/components/autofill/core/browser/search_field.cc4
-rw-r--r--chromium/components/autofill/core/browser/search_field.h3
-rw-r--r--chromium/components/autofill/core/browser/strike_database.cc55
-rw-r--r--chromium/components/autofill/core/browser/strike_database.h33
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_base.cc47
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_base.h35
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc46
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h36
-rw-r--r--chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc289
-rw-r--r--chromium/components/autofill/core/browser/strike_database_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/suggestion.cc2
-rw-r--r--chromium/components/autofill/core/browser/suggestion.h2
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection.cc8
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection.h4
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection_unittest.cc80
-rw-r--r--chromium/components/autofill/core/browser/suggestion_test_helpers.h6
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.cc21
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.h10
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator.cc12
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator.h5
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc39
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h41
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_provider.h2
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_manager.cc28
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_manager.h17
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc13
-rw-r--r--chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h20
-rw-r--r--chromium/components/autofill/core/browser/test_personal_data_manager.cc7
-rw-r--r--chromium/components/autofill/core/browser/test_personal_data_manager.h13
-rw-r--r--chromium/components/autofill/core/browser/test_strike_database.cc2
-rw-r--r--chromium/components/autofill/core/browser/test_strike_database.h2
-rw-r--r--chromium/components/autofill/core/browser/travel_field.cc53
-rw-r--r--chromium/components/autofill/core/browser/travel_field.h33
-rw-r--r--chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc77
-rw-r--r--chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h60
-rw-r--r--chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc3
-rw-r--r--chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc30
-rw-r--r--chromium/components/autofill/core/browser/validation.cc7
-rw-r--r--chromium/components/autofill/core/browser/validation.h2
-rw-r--r--chromium/components/autofill/core/browser/validation_unittest.cc66
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_change.h25
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc9
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h9
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc41
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h5
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc45
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc2
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc15
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc8
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc826
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc17
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc27
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h5
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc18
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h6
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc10
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h1
-rw-r--r--chromium/components/autofill/core/common/autofill_features.cc34
-rw-r--r--chromium/components/autofill/core/common/autofill_features.h9
-rw-r--r--chromium/components/autofill/core/common/autofill_prefs_unittest.cc3
-rw-r--r--chromium/components/autofill/core/common/autofill_regex_constants.cc70
-rw-r--r--chromium/components/autofill/core/common/autofill_regex_constants.h5
-rw-r--r--chromium/components/autofill/core/common/autofill_regexes_unittest.cc116
-rw-r--r--chromium/components/autofill/core/common/autofill_switches.cc11
-rw-r--r--chromium/components/autofill/core/common/autofill_switches.h2
-rw-r--r--chromium/components/autofill/core/common/autofill_util.cc3
-rw-r--r--chromium/components/autofill/core/common/autofill_util_unittest.cc30
-rw-r--r--chromium/components/autofill/core/common/form_field_data.h2
-rw-r--r--chromium/components/autofill/core/common/password_generation_util.cc23
-rw-r--r--chromium/components/autofill/core/common/password_generation_util.h25
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger.cc10
-rw-r--r--chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_agent.mm2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios.h2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios.mm2
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h3
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm4
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h1
-rw-r--r--chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm4
-rw-r--r--chromium/components/autofill/ios/browser/autofill_util.mm7
-rw-r--r--chromium/components/autofill/ios/browser/js_suggestion_manager.mm1
-rw-r--r--chromium/components/autofill/ios/browser/resources/autofill_controller.js2
-rw-r--r--chromium/components/autofill/ios/form_util/form_activity_tab_helper.h3
-rw-r--r--chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm3
220 files changed, 9150 insertions, 4219 deletions
diff --git a/chromium/components/autofill/OWNERS b/chromium/components/autofill/OWNERS
index f1fa6a5c923..09f6941e2cc 100644
--- a/chromium/components/autofill/OWNERS
+++ b/chromium/components/autofill/OWNERS
@@ -4,5 +4,6 @@ ftirelo@chromium.org
mahmadi@chromium.org
rogerm@chromium.org
sebsg@chromium.org
+tmartino@chromium.org
# COMPONENT: UI>Browser>Autofill
diff --git a/chromium/components/autofill/android/BUILD.gn b/chromium/components/autofill/android/BUILD.gn
index c952a263e04..bd2ac36e3c9 100644
--- a/chromium/components/autofill/android/BUILD.gn
+++ b/chromium/components/autofill/android/BUILD.gn
@@ -7,22 +7,24 @@ import("//build/config/android/rules.gni")
java_strings_grd("autofill_strings_grd") {
grd_file = "java/strings/autofill_strings.grd"
outputs = [
+ "values/autofill_strings.xml",
"values-am/autofill_strings.xml",
"values-ar/autofill_strings.xml",
"values-bg/autofill_strings.xml",
+ "values-bn/autofill_strings.xml",
"values-ca/autofill_strings.xml",
"values-cs/autofill_strings.xml",
"values-da/autofill_strings.xml",
"values-de/autofill_strings.xml",
"values-el/autofill_strings.xml",
- "values/autofill_strings.xml",
"values-en-rGB/autofill_strings.xml",
"values-es/autofill_strings.xml",
"values-es-rUS/autofill_strings.xml",
+ "values-et/autofill_strings.xml",
"values-fa/autofill_strings.xml",
"values-fi/autofill_strings.xml",
- "values-tl/autofill_strings.xml",
"values-fr/autofill_strings.xml",
+ "values-gu/autofill_strings.xml",
"values-hi/autofill_strings.xml",
"values-hr/autofill_strings.xml",
"values-hu/autofill_strings.xml",
@@ -30,11 +32,15 @@ java_strings_grd("autofill_strings_grd") {
"values-it/autofill_strings.xml",
"values-iw/autofill_strings.xml",
"values-ja/autofill_strings.xml",
+ "values-kn/autofill_strings.xml",
"values-ko/autofill_strings.xml",
"values-lt/autofill_strings.xml",
"values-lv/autofill_strings.xml",
- "values-nl/autofill_strings.xml",
+ "values-ml/autofill_strings.xml",
+ "values-mr/autofill_strings.xml",
+ "values-ms/autofill_strings.xml",
"values-nb/autofill_strings.xml",
+ "values-nl/autofill_strings.xml",
"values-pl/autofill_strings.xml",
"values-pt-rBR/autofill_strings.xml",
"values-pt-rPT/autofill_strings.xml",
@@ -45,7 +51,10 @@ java_strings_grd("autofill_strings_grd") {
"values-sr/autofill_strings.xml",
"values-sv/autofill_strings.xml",
"values-sw/autofill_strings.xml",
+ "values-ta/autofill_strings.xml",
+ "values-te/autofill_strings.xml",
"values-th/autofill_strings.xml",
+ "values-tl/autofill_strings.xml",
"values-tr/autofill_strings.xml",
"values-uk/autofill_strings.xml",
"values-vi/autofill_strings.xml",
@@ -65,6 +74,7 @@ android_resources("autofill_java_resources") {
java_cpp_enum("autofill_core_browser_java_enums") {
sources = [
+ "../core/browser/accessory_sheet_data.h",
"../core/browser/popup_item_ids.h",
]
}
diff --git a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
index f0114b9fa9f..aa4a395dbda 100644
--- a/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
+++ b/chromium/components/autofill/android/java/src/org/chromium/components/autofill/FormFieldData.java
@@ -20,12 +20,13 @@ public class FormFieldData {
/**
* Define the control types supported by android.view.autofill.AutofillValue.
*/
- @IntDef({TYPE_TEXT, TYPE_TOGGLE, TYPE_LIST})
+ @IntDef({ControlType.TEXT, ControlType.TOGGLE, ControlType.LIST})
@Retention(RetentionPolicy.SOURCE)
- public @interface ControlType {}
- public static final int TYPE_TEXT = 0;
- public static final int TYPE_TOGGLE = 1;
- public static final int TYPE_LIST = 2;
+ public @interface ControlType {
+ int TEXT = 0;
+ int TOGGLE = 1;
+ int LIST = 2;
+ }
public final String mLabel;
public final String mName;
@@ -63,11 +64,11 @@ public class FormFieldData {
mOptionContents = optionContents;
mIsChecked = isChecked;
if (mOptionValues != null && mOptionValues.length != 0) {
- mControlType = TYPE_LIST;
+ mControlType = ControlType.LIST;
} else if (isCheckField) {
- mControlType = TYPE_TOGGLE;
+ mControlType = ControlType.TOGGLE;
} else {
- mControlType = TYPE_TEXT;
+ mControlType = ControlType.TEXT;
}
mMaxLength = maxLength;
mHeuristicType = heuristicType;
diff --git a/chromium/components/autofill/android/java/strings/autofill_strings.grd b/chromium/components/autofill/android/java/strings/autofill_strings.grd
index cd32decc6f7..e4e1b595e83 100644
--- a/chromium/components/autofill/android/java/strings/autofill_strings.grd
+++ b/chromium/components/autofill/android/java/strings/autofill_strings.grd
@@ -6,6 +6,7 @@
<output filename="values-am/autofill_strings.xml" lang="am" type="android" />
<output filename="values-ar/autofill_strings.xml" lang="ar" type="android" />
<output filename="values-bg/autofill_strings.xml" lang="bg" type="android" />
+ <output filename="values-bn/autofill_strings.xml" lang="bn" type="android" />
<output filename="values-ca/autofill_strings.xml" lang="ca" type="android" />
<output filename="values-cs/autofill_strings.xml" lang="cs" type="android" />
<output filename="values-da/autofill_strings.xml" lang="da" type="android" />
@@ -15,20 +16,26 @@
<output filename="values-en-rGB/autofill_strings.xml" lang="en-GB" type="android" />
<output filename="values-es/autofill_strings.xml" lang="es" type="android" />
<output filename="values-es-rUS/autofill_strings.xml" lang="es-419" type="android" />
+ <output filename="values-et/autofill_strings.xml" lang="et" type="android" />
<output filename="values-fa/autofill_strings.xml" lang="fa" type="android" />
<output filename="values-fi/autofill_strings.xml" lang="fi" type="android" />
<output filename="values-tl/autofill_strings.xml" lang="fil" type="android" />
<output filename="values-fr/autofill_strings.xml" lang="fr" type="android" />
+ <output filename="values-gu/autofill_strings.xml" lang="gu" type="android" />
+ <output filename="values-iw/autofill_strings.xml" lang="he" type="android" />
<output filename="values-hi/autofill_strings.xml" lang="hi" type="android" />
<output filename="values-hr/autofill_strings.xml" lang="hr" type="android" />
<output filename="values-hu/autofill_strings.xml" lang="hu" type="android" />
<output filename="values-in/autofill_strings.xml" lang="id" type="android" />
<output filename="values-it/autofill_strings.xml" lang="it" type="android" />
- <output filename="values-iw/autofill_strings.xml" lang="he" type="android" />
<output filename="values-ja/autofill_strings.xml" lang="ja" type="android" />
+ <output filename="values-kn/autofill_strings.xml" lang="kn" type="android" />
<output filename="values-ko/autofill_strings.xml" lang="ko" type="android" />
<output filename="values-lt/autofill_strings.xml" lang="lt" type="android" />
<output filename="values-lv/autofill_strings.xml" lang="lv" type="android" />
+ <output filename="values-ml/autofill_strings.xml" lang="ml" type="android" />
+ <output filename="values-mr/autofill_strings.xml" lang="mr" type="android" />
+ <output filename="values-ms/autofill_strings.xml" lang="ms" type="android" />
<output filename="values-nl/autofill_strings.xml" lang="nl" type="android" />
<output filename="values-nb/autofill_strings.xml" lang="no" type="android" />
<output filename="values-pl/autofill_strings.xml" lang="pl" type="android" />
@@ -41,6 +48,8 @@
<output filename="values-sr/autofill_strings.xml" lang="sr" type="android" />
<output filename="values-sv/autofill_strings.xml" lang="sv" type="android" />
<output filename="values-sw/autofill_strings.xml" lang="sw" type="android" />
+ <output filename="values-ta/autofill_strings.xml" lang="ta" type="android" />
+ <output filename="values-te/autofill_strings.xml" lang="te" type="android" />
<output filename="values-th/autofill_strings.xml" lang="th" type="android" />
<output filename="values-tr/autofill_strings.xml" lang="tr" type="android" />
<output filename="values-uk/autofill_strings.xml" lang="uk" type="android" />
diff --git a/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc b/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
index 1a08f64bb43..c0dc02de81e 100644
--- a/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
+++ b/chromium/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -11,6 +11,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -207,7 +208,7 @@ class FakeAutofillAgent : public mojom::AutofillAgent {
void SetFocusRequiresScroll(bool require) override {}
- void SetQueryPasswordSuggestion(bool query) override{};
+ void SetQueryPasswordSuggestion(bool query) override {}
void GetElementFormAndFieldData(
const std::vector<std::string>& selectors,
diff --git a/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc b/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
index 2d2534c264f..d750fa4aaba 100644
--- a/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
+++ b/chromium/components/autofill/content/common/autofill_types_struct_traits_unittest.cc
@@ -4,6 +4,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
diff --git a/chromium/components/autofill/content/renderer/form_autofill_util.cc b/chromium/components/autofill/content/renderer/form_autofill_util.cc
index c446763ff7a..f3894b9cee3 100644
--- a/chromium/components/autofill/content/renderer/form_autofill_util.cc
+++ b/chromium/components/autofill/content/renderer/form_autofill_util.cc
@@ -16,6 +16,7 @@
#include "base/command_line.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
+#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
@@ -98,6 +99,15 @@ enum FieldFilterMask {
FILTER_NON_FOCUSABLE_ELEMENTS,
};
+// Returns whether sending autofill field metadata to the server is enabled.
+// TODO(crbug.com/938804): Remove this when button titles are crowdsourced in
+// all channels.
+bool IsAutofillFieldMetadataEnabled() {
+ static base::NoDestructor<std::string> kGroupName(
+ base::FieldTrialList::FindFullName("AutofillFieldMetadata"));
+ return base::StartsWith(*kGroupName, "Enabled", base::CompareCase::SENSITIVE);
+}
+
void TruncateString(base::string16* str, size_t max_length) {
if (str->length() > max_length)
str->resize(max_length);
@@ -1415,6 +1425,11 @@ bool UnownedFormElementsAndFieldSetsToFormData(
FormData* form,
FormFieldData* field) {
form->origin = GetCanonicalOriginForDocument(document);
+ if (IsAutofillFieldMetadataEnabled() && !document.Body().IsNull()) {
+ SCOPED_UMA_HISTOGRAM_TIMER(
+ "PasswordManager.ButtonTitlePerformance.NoFormTag");
+ form->button_titles = InferButtonTitlesForForm(document.Body());
+ }
if (document.GetFrame() && document.GetFrame()->Top()) {
form->main_frame_origin = document.GetFrame()->Top()->GetSecurityOrigin();
} else {
@@ -1791,6 +1806,11 @@ bool WebFormElementToFormData(
form->unique_renderer_id = form_element.UniqueRendererFormId();
form->origin = GetCanonicalOriginForDocument(frame->GetDocument());
form->action = GetCanonicalActionForForm(form_element);
+ if (IsAutofillFieldMetadataEnabled()) {
+ SCOPED_UMA_HISTOGRAM_TIMER(
+ "PasswordManager.ButtonTitlePerformance.HasFormTag");
+ form->button_titles = InferButtonTitlesForForm(form_element);
+ }
if (frame->Top()) {
form->main_frame_origin = frame->Top()->GetSecurityOrigin();
} else {
diff --git a/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc b/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc
index 48ce8bb59a6..f9b4f4e2edf 100644
--- a/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc
+++ b/chromium/components/autofill/content/renderer/form_autofill_util_browsertest.cc
@@ -316,7 +316,7 @@ TEST_F(FormAutofillUtilsTest, InferButtonTitleForFormTest_TooLongTitle) {
std::string kFormHtml = "<form id='target'>";
for (int i = 0; i < 10; i++) {
std::string kFieldHtml =
- "<input type='button' value='" + base::IntToString(i) + title + "'>";
+ "<input type='button' value='" + base::NumberToString(i) + title + "'>";
kFormHtml += kFieldHtml;
}
kFormHtml += "</form>";
diff --git a/chromium/components/autofill/content/renderer/form_tracker.cc b/chromium/components/autofill/content/renderer/form_tracker.cc
index 3b2fe682d38..f5360b1c02c 100644
--- a/chromium/components/autofill/content/renderer/form_tracker.cc
+++ b/chromium/components/autofill/content/renderer/form_tracker.cc
@@ -4,6 +4,7 @@
#include "components/autofill/content/renderer/form_tracker.h"
+#include "base/bind.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/render_frame.h"
@@ -155,8 +156,9 @@ void FormTracker::DidCommitProvisionalLoad(bool is_same_document_navigation,
FireSubmissionIfFormDisappear(SubmissionSource::SAME_DOCUMENT_NAVIGATION);
}
-void FormTracker::DidStartProvisionalLoad(WebDocumentLoader* document_loader,
- bool is_content_initiated) {
+void FormTracker::DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(form_tracker_sequence_checker_);
blink::WebLocalFrame* navigated_frame = render_frame()->GetWebFrame();
// Ony handle main frame.
@@ -167,15 +169,11 @@ void FormTracker::DidStartProvisionalLoad(WebDocumentLoader* document_loader,
// the user is performing actions outside the page (e.g. typed url,
// history navigation). We don't want to trigger saving in these cases.
- // We are interested only in content initiated navigations. Explicit browser
- // initiated navigations (e.g. via omnibox) are discarded here. Similarly
- // PlzNavigate navigations originating from the browser are discarded because
- // they were already processed as a content initiated one
- // (i.e. DidStartProvisionalLoad is called twice in this case). The check for
- // kWebNavigationTypeLinkClicked is reliable only for content initiated
- // navigations.
- if (is_content_initiated && document_loader->GetNavigationType() !=
- blink::kWebNavigationTypeLinkClicked) {
+ // We are interested only in content-initiated navigations. Explicit browser
+ // initiated navigations (e.g. via omnibox) don't have a navigation type
+ // and are discarded here.
+ if (navigation_type.has_value() &&
+ navigation_type.value() != blink::kWebNavigationTypeLinkClicked) {
FireProbablyFormSubmitted();
}
}
diff --git a/chromium/components/autofill/content/renderer/form_tracker.h b/chromium/components/autofill/content/renderer/form_tracker.h
index b7e7bcd4b3f..b31d9b05a8c 100644
--- a/chromium/components/autofill/content/renderer/form_tracker.h
+++ b/chromium/components/autofill/content/renderer/form_tracker.h
@@ -91,8 +91,9 @@ class FormTracker : public content::RenderFrameObserver {
// content::RenderFrameObserver:
void DidCommitProvisionalLoad(bool is_same_document_navigation,
ui::PageTransition transition) override;
- void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) override;
+ void DidStartNavigation(
+ const GURL& url,
+ base::Optional<blink::WebNavigationType> navigation_type) override;
void FrameDetached() override;
void WillSendSubmitEvent(const blink::WebFormElement& form) override;
void WillSubmitForm(const blink::WebFormElement& form) override;
diff --git a/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc b/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc
index 40676cad5c5..88821bf6f22 100644
--- a/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc
+++ b/chromium/components/autofill/content/renderer/page_form_analyser_logger.cc
@@ -6,7 +6,11 @@
#include <utility>
+#include "base/strings/string_util.h"
#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_element.h"
+#include "third_party/blink/public/web/web_input_element.h"
+#include "third_party/blink/public/web/web_node.h"
namespace autofill {
@@ -38,11 +42,31 @@ void PageFormAnalyserLogger::Flush() {
text.clear();
text += "[DOM] ";
text += entry.message;
- for (unsigned i = 0; i < entry.nodes.size(); ++i)
- text += " %o";
+
+ std::vector<blink::WebNode> nodesToLog;
+ for (unsigned i = 0; i < entry.nodes.size(); ++i) {
+ if (entry.nodes[i].IsElementNode()) {
+ const blink::WebElement element =
+ entry.nodes[i].ToConst<blink::WebElement>();
+ const blink::WebInputElement* webInputElement =
+ blink::ToWebInputElement(&element);
+
+ // Filter out password inputs with values from being logged, as their
+ // values are also logged.
+ const bool shouldObfuscate =
+ webInputElement &&
+ webInputElement->IsPasswordFieldForAutofill() &&
+ !webInputElement->Value().IsEmpty();
+
+ if (!shouldObfuscate) {
+ text += " %o";
+ nodesToLog.push_back(element);
+ }
+ }
+ }
blink::WebConsoleMessage message(level, blink::WebString::FromUTF8(text));
- message.nodes = std::move(entry.nodes); // avoids copying node vectors.
+ message.nodes = std::move(nodesToLog); // avoids copying node vectors.
frame_->AddMessageToConsole(message);
}
}
diff --git a/chromium/components/autofill/content/renderer/page_passwords_analyser.cc b/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
index 7a8d2087700..ef70bae8012 100644
--- a/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
+++ b/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
@@ -95,7 +95,7 @@ struct FormInputCollection {
} \
}; \
base::LazyInstance<re2::RE2, LabelPatternLazyInstanceTraits_##NAME> NAME = \
- LAZY_INSTANCE_INITIALIZER;
+ LAZY_INSTANCE_INITIALIZER
DECLARE_LAZY_MATCHER(ignored_characters_matcher, R"(\W)");
DECLARE_LAZY_MATCHER(username_matcher, R"(user(name)?|login)");
diff --git a/chromium/components/autofill/content/renderer/password_autofill_agent.cc b/chromium/components/autofill/content/renderer/password_autofill_agent.cc
index ed933f790ea..e46c75175c3 100644
--- a/chromium/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/chromium/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1015,10 +1015,6 @@ bool PasswordAutofillAgent::ShowSuggestions(const WebInputElement& element,
element != password_info->password_field))
return true;
- UMA_HISTOGRAM_BOOLEAN(
- "PasswordManager.AutocompletePopupSuppressedByGeneration",
- generation_popup_showing);
-
if (generation_popup_showing)
return false;
@@ -1351,9 +1347,8 @@ void PasswordAutofillAgent::OnDestruct() {
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
-void PasswordAutofillAgent::DidStartProvisionalLoad(
- blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) {
+void PasswordAutofillAgent::ReadyToCommitNavigation(
+ blink::WebDocumentLoader* document_loader) {
std::unique_ptr<RendererSavePasswordProgressLogger> logger;
if (logging_state_active_) {
logger.reset(new RendererSavePasswordProgressLogger(
diff --git a/chromium/components/autofill/content/renderer/password_autofill_agent.h b/chromium/components/autofill/content/renderer/password_autofill_agent.h
index 01cc65b4e55..520d2ccb2ed 100644
--- a/chromium/components/autofill/content/renderer/password_autofill_agent.h
+++ b/chromium/components/autofill/content/renderer/password_autofill_agent.h
@@ -248,8 +248,8 @@ class PasswordAutofillAgent : public content::RenderFrameObserver,
// RenderFrameObserver:
void DidFinishDocumentLoad() override;
void DidFinishLoad() override;
- void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
- bool is_content_initiated) override;
+ void ReadyToCommitNavigation(
+ blink::WebDocumentLoader* document_loader) override;
void WillCommitProvisionalLoad() override;
void DidCommitProvisionalLoad(bool is_same_document_navigation,
ui::PageTransition transition) override;
diff --git a/chromium/components/autofill/content/renderer/password_generation_agent.cc b/chromium/components/autofill/content/renderer/password_generation_agent.cc
index deaa4959b13..67693adae4d 100644
--- a/chromium/components/autofill/content/renderer/password_generation_agent.cc
+++ b/chromium/components/autofill/content/renderer/password_generation_agent.cc
@@ -9,6 +9,7 @@
#include <utility>
#include "base/auto_reset.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/stl_util.h"
@@ -453,6 +454,8 @@ void PasswordGenerationAgent::GeneratedPasswordAccepted(
password_generation::PASSWORD_ACCEPTED);
LogMessage(Logger::STRING_GENERATION_RENDERER_GENERATED_PASSWORD_ACCEPTED);
for (auto& password_element : current_generation_item_->password_elements_) {
+ base::AutoReset<bool> auto_reset_update_confirmation_password(
+ &current_generation_item_->updating_other_password_fileds_, true);
password_element.SetAutofillValue(blink::WebString::FromUTF16(password));
// setAutofillValue() above may have resulted in JavaScript closing the
// frame.
@@ -691,7 +694,6 @@ bool PasswordGenerationAgent::FocusedNodeHasChanged(
const blink::WebElement web_element = node.ToConst<blink::WebElement>();
if (!web_element.GetDocument().GetFrame()) {
- AutomaticGenerationStatusChanged(false);
return false;
}
@@ -738,7 +740,6 @@ bool PasswordGenerationAgent::FocusedNodeHasChanged(
return true;
}
- AutomaticGenerationStatusChanged(false);
return false;
}
@@ -746,7 +747,8 @@ void PasswordGenerationAgent::DidEndTextFieldEditing(
const blink::WebInputElement& element) {
if (!element.IsNull() && current_generation_item_ &&
element == current_generation_item_->generation_element_) {
- AutomaticGenerationStatusChanged(false);
+ if (!current_generation_item_->password_is_generated_)
+ AutomaticGenerationStatusChanged(false);
current_generation_item_->generation_element_.SetShouldRevealPassword(
false);
}
@@ -897,6 +899,9 @@ void PasswordGenerationAgent::MaybeCreateCurrentGenerationItem(
? password_agent_->GetPasswordFormFromUnownedInputElements()
: password_agent_->GetPasswordFormFromWebForm(element.Form());
+ if (!password_form)
+ return;
+
std::vector<blink::WebInputElement> passwords = {element};
WebFormControlElement confirmation_password =
diff --git a/chromium/components/autofill/content/renderer/prefilled_values_detector.cc b/chromium/components/autofill/content/renderer/prefilled_values_detector.cc
index c20059cf053..80290a4595f 100644
--- a/chromium/components/autofill/content/renderer/prefilled_values_detector.cc
+++ b/chromium/components/autofill/content/renderer/prefilled_values_detector.cc
@@ -21,7 +21,7 @@ const base::flat_set<std::string, std::less<>>& KnownUsernamePlaceholders() {
"3~15个字符,中文字符7个以内",
"benutzername",
"client id",
- "codice titolare"
+ "codice titolare",
"digite seu cpf ou e-mail",
"ds logon username",
"email",
diff --git a/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc b/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
index 46aae75d3e6..9001bcd8f9b 100644
--- a/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
+++ b/chromium/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
@@ -9,8 +9,6 @@
#include "base/values.h"
#include "third_party/blink/public/web/web_form_control_element.h"
-using base::UintToString;
-
namespace autofill {
RendererSavePasswordProgressLogger::RendererSavePasswordProgressLogger(
@@ -30,7 +28,8 @@ void RendererSavePasswordProgressLogger::LogElementName(
const blink::WebFormControlElement& element) {
std::string text =
"name = " + ScrubElementID(element.NameForAutofill().Utf8()) +
- ", renderer_id = " + UintToString(element.UniqueRendererFormControlId());
+ ", renderer_id = " +
+ base::NumberToString(element.UniqueRendererFormControlId());
LogValue(label, base::Value(text));
}
diff --git a/chromium/components/autofill/core/browser/BUILD.gn b/chromium/components/autofill/core/browser/BUILD.gn
index 9cf6e445d70..fea04db6961 100644
--- a/chromium/components/autofill/core/browser/BUILD.gn
+++ b/chromium/components/autofill/core/browser/BUILD.gn
@@ -18,6 +18,8 @@ jumbo_static_library("browser") {
"address_combobox_model.h",
"address_field.cc",
"address_field.h",
+ "address_form_label_formatter.cc",
+ "address_form_label_formatter.h",
"address_i18n.cc",
"address_i18n.h",
"address_normalization_manager.cc",
@@ -92,6 +94,8 @@ jumbo_static_library("browser") {
"autofill_wallet_model_type_controller.h",
"card_unmask_delegate.cc",
"card_unmask_delegate.h",
+ "contact_form_label_formatter.cc",
+ "contact_form_label_formatter.h",
"contact_info.cc",
"contact_info.h",
"country_combobox_model.cc",
@@ -125,6 +129,10 @@ jumbo_static_library("browser") {
"form_structure.h",
"form_types.cc",
"form_types.h",
+ "label_formatter.cc",
+ "label_formatter.h",
+ "label_formatter_utils.cc",
+ "label_formatter_utils.h",
"legacy_strike_database.cc",
"legacy_strike_database.h",
"legal_message_line.cc",
@@ -133,6 +141,13 @@ jumbo_static_library("browser") {
"local_card_migration_manager.h",
"local_card_migration_strike_database.cc",
"local_card_migration_strike_database.h",
+ "metrics/address_form_event_logger.cc",
+ "metrics/address_form_event_logger.h",
+ "metrics/credit_card_form_event_logger.cc",
+ "metrics/credit_card_form_event_logger.h",
+ "metrics/form_event_logger_base.cc",
+ "metrics/form_event_logger_base.h",
+ "metrics/form_events.h",
"name_field.cc",
"name_field.h",
"password_requirements_spec_fetcher.h",
@@ -161,6 +176,8 @@ jumbo_static_library("browser") {
"phone_number_i18n.h",
"popup_item_ids.h",
"popup_types.h",
+ "price_field.cc",
+ "price_field.h",
"randomized_encoder.cc",
"randomized_encoder.h",
"rationalization_util.cc",
@@ -179,6 +196,8 @@ jumbo_static_library("browser") {
"strike_database.h",
"strike_database_integrator_base.cc",
"strike_database_integrator_base.h",
+ "strike_database_integrator_test_strike_database.cc",
+ "strike_database_integrator_test_strike_database.h",
"subkey_requester.cc",
"subkey_requester.h",
"suggestion.cc",
@@ -188,6 +207,8 @@ jumbo_static_library("browser") {
"sync_utils.h",
"test_data_creator.cc",
"test_data_creator.h",
+ "travel_field.cc",
+ "travel_field.h",
"ui/card_unmask_prompt_controller.h",
"ui/card_unmask_prompt_controller_impl.cc",
"ui/card_unmask_prompt_controller_impl.h",
@@ -252,6 +273,8 @@ jumbo_static_library("browser") {
"autofill_save_card_infobar_delegate_mobile.cc",
"autofill_save_card_infobar_delegate_mobile.h",
"autofill_save_card_infobar_mobile.h",
+ "ui/card_expiration_date_fix_flow_view_delegate_mobile.cc",
+ "ui/card_expiration_date_fix_flow_view_delegate_mobile.h",
"ui/card_name_fix_flow_view_delegate_mobile.cc",
"ui/card_name_fix_flow_view_delegate_mobile.h",
]
@@ -295,6 +318,7 @@ jumbo_static_library("browser") {
"//base",
"//base:i18n",
"//components/data_use_measurement/core",
+ "//components/google/core/common",
"//components/history/core/browser",
"//components/infobars/core",
"//components/keyed_service/core",
@@ -375,6 +399,8 @@ jumbo_static_library("test_support") {
"test_autofill_manager.h",
"test_autofill_profile_validator.cc",
"test_autofill_profile_validator.h",
+ "test_autofill_profile_validator_delayed.cc",
+ "test_autofill_profile_validator_delayed.h",
"test_autofill_provider.cc",
"test_autofill_provider.h",
"test_credit_card_save_manager.cc",
@@ -390,8 +416,6 @@ jumbo_static_library("test_support") {
"test_legacy_strike_database.h",
"test_local_card_migration_manager.cc",
"test_local_card_migration_manager.h",
- "test_local_card_migration_strike_database.cc",
- "test_local_card_migration_strike_database.h",
"test_personal_data_manager.cc",
"test_personal_data_manager.h",
"test_region_data_loader.cc",
@@ -517,17 +541,16 @@ source_set("unit_tests") {
"country_names_unittest.cc",
"credit_card_field_unittest.cc",
"credit_card_save_manager_unittest.cc",
- "credit_card_save_strike_database_unittest.cc",
"credit_card_unittest.cc",
"field_candidates_unittest.cc",
"field_filler_unittest.cc",
"form_data_importer_unittest.cc",
"form_field_unittest.cc",
"form_structure_unittest.cc",
+ "label_formatter_utils_unittest.cc",
"legacy_strike_database_unittest.cc",
"legal_message_line_unittest.cc",
"local_card_migration_manager_unittest.cc",
- "local_card_migration_strike_database_unittest.cc",
"name_field_unittest.cc",
"password_generator_fips181_unittest.cc",
"password_generator_unittest.cc",
@@ -540,11 +563,13 @@ source_set("unit_tests") {
"phone_field_unittest.cc",
"phone_number_i18n_unittest.cc",
"phone_number_unittest.cc",
+ "price_field_unittest.cc",
"proto/legacy_proto_bridge_unittest.cc",
"randomized_encoder_unittest.cc",
"rationalization_util_unittest.cc",
"region_combobox_model_unittest.cc",
"search_field_unittest.cc",
+ "strike_database_integrator_test_strike_database_unittest.cc",
"strike_database_unittest.cc",
"subkey_requester_unittest.cc",
"suggestion_selection_unittest.cc",
@@ -600,6 +625,7 @@ source_set("unit_tests") {
"//components/ukm:test_support",
"//components/variations",
"//components/variations:test_support",
+ "//components/variations/net",
"//components/version_info:version_info",
"//components/webdata/common",
"//components/webdata_services:test_support",
diff --git a/chromium/components/autofill/core/browser/DEPS b/chromium/components/autofill/core/browser/DEPS
index 35cb68b74d4..3536f9f5ce0 100644
--- a/chromium/components/autofill/core/browser/DEPS
+++ b/chromium/components/autofill/core/browser/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+components/data_use_measurement/core",
+ "+components/google/core/common/google_util.h",
"+components/grit/components_scaled_resources.h",
"+components/history/core/browser",
"+components/infobars/core",
diff --git a/chromium/components/autofill/core/browser/OWNERS b/chromium/components/autofill/core/browser/OWNERS
new file mode 100644
index 00000000000..013fa313149
--- /dev/null
+++ b/chromium/components/autofill/core/browser/OWNERS
@@ -0,0 +1 @@
+parastoog@google.com
diff --git a/chromium/components/autofill/core/browser/accessory_sheet_data.cc b/chromium/components/autofill/core/browser/accessory_sheet_data.cc
index dc0eb25bd7d..75cce7ffa5b 100644
--- a/chromium/components/autofill/core/browser/accessory_sheet_data.cc
+++ b/chromium/components/autofill/core/browser/accessory_sheet_data.cc
@@ -67,8 +67,9 @@ bool FooterCommand::operator==(const FooterCommand& fc) const {
return display_text_ == fc.display_text_;
}
-AccessorySheetData::AccessorySheetData(const base::string16& title)
- : title_(title) {}
+AccessorySheetData::AccessorySheetData(FallbackSheetType sheet_type,
+ const base::string16& title)
+ : sheet_type_(sheet_type), title_(title) {}
AccessorySheetData::AccessorySheetData(const AccessorySheetData& data) =
default;
diff --git a/chromium/components/autofill/core/browser/accessory_sheet_data.h b/chromium/components/autofill/core/browser/accessory_sheet_data.h
index 5e439d787c1..384079b895e 100644
--- a/chromium/components/autofill/core/browser/accessory_sheet_data.h
+++ b/chromium/components/autofill/core/browser/accessory_sheet_data.h
@@ -87,14 +87,20 @@ class FooterCommand {
base::string16 display_text_;
};
+// GENERATED_JAVA_ENUM_PACKAGE: (
+// org.chromium.chrome.browser.autofill.keyboard_accessory)
+enum class FallbackSheetType {
+ // Indicates the data type to which an AccessorySheetData object corresponds.
+ PASSWORD,
+ CREDIT_CARD
+};
+
// Represents the contents of a bottom sheet tab below the keyboard accessory,
// which can correspond to passwords, credit cards, or profiles data.
-//
-// TODO(crbug.com/902425): Add a field to indicate if this corresponds to
-// password, profile, or credit card data.
class AccessorySheetData {
public:
- explicit AccessorySheetData(const base::string16& title);
+ explicit AccessorySheetData(FallbackSheetType sheet_type,
+ const base::string16& title);
AccessorySheetData(const AccessorySheetData& data);
AccessorySheetData(AccessorySheetData&& data);
@@ -104,6 +110,7 @@ class AccessorySheetData {
AccessorySheetData& operator=(AccessorySheetData&& data);
const base::string16& title() const { return title_; }
+ FallbackSheetType get_sheet_type() const { return sheet_type_; }
void add_user_info(UserInfo user_info) {
user_info_list_.emplace_back(std::move(user_info));
@@ -126,6 +133,7 @@ class AccessorySheetData {
bool operator==(const AccessorySheetData& data) const;
private:
+ FallbackSheetType sheet_type_;
base::string16 title_;
std::vector<UserInfo> user_info_list_;
std::vector<FooterCommand> footer_commands_;
diff --git a/chromium/components/autofill/core/browser/account_info_getter.h b/chromium/components/autofill/core/browser/account_info_getter.h
index 7d71b5fae99..44fa238ebec 100644
--- a/chromium/components/autofill/core/browser/account_info_getter.h
+++ b/chromium/components/autofill/core/browser/account_info_getter.h
@@ -17,7 +17,7 @@ class AccountInfoGetter {
// Returns the account info that should be used when communicating with the
// Payments server. The AccountInfo could be empty if there is no account to
// be used by the Payments server.
- virtual AccountInfo GetAccountInfoForPaymentsServer() const = 0;
+ virtual CoreAccountInfo GetAccountInfoForPaymentsServer() const = 0;
// Returns true - When user is both signed-in and enabled sync.
// Returns false - When user is not signed-in or does not have sync the
diff --git a/chromium/components/autofill/core/browser/address_form_label_formatter.cc b/chromium/components/autofill/core/browser/address_form_label_formatter.cc
new file mode 100644
index 00000000000..604dd7882da
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_form_label_formatter.cc
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/address_form_label_formatter.h"
+
+namespace autofill {
+
+AddressFormLabelFormatter::AddressFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types)
+ : LabelFormatter(app_locale, focused_field_type, field_types) {
+ for (const ServerFieldType& type : field_types) {
+ if (type != focused_field_type && type != ADDRESS_HOME_COUNTRY &&
+ type != ADDRESS_BILLING_COUNTRY) {
+ field_types_for_labels_.push_back(type);
+ }
+ }
+}
+
+AddressFormLabelFormatter::~AddressFormLabelFormatter() {}
+
+std::vector<base::string16> AddressFormLabelFormatter::GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const {
+ // TODO(crbug.com/936168): Implement GetLabels().
+ std::vector<base::string16> labels;
+ return labels;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_form_label_formatter.h b/chromium/components/autofill/core/browser/address_form_label_formatter.h
new file mode 100644
index 00000000000..1f0c4850a3d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_form_label_formatter.h
@@ -0,0 +1,39 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_FORM_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_FORM_LABEL_FORMATTER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+
+// A LabelFormatter that creates Suggestions' disambiguating labels for forms
+// with name and address fields and without email or phone fields.
+class AddressFormLabelFormatter : public LabelFormatter {
+ public:
+ AddressFormLabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types);
+
+ ~AddressFormLabelFormatter() override;
+
+ std::vector<base::string16> GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const override;
+
+ private:
+ // A collection of field types that can be used to make labels. This
+ // collection excludes the focused_field_type_ and address countries.
+ std::vector<ServerFieldType> field_types_for_labels_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_FORM_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/address_i18n_unittest.cc b/chromium/components/autofill/core/browser/address_i18n_unittest.cc
index 2647d888fe2..0f96565a4b7 100644
--- a/chromium/components/autofill/core/browser/address_i18n_unittest.cc
+++ b/chromium/components/autofill/core/browser/address_i18n_unittest.cc
@@ -55,7 +55,7 @@ TEST_P(FieldTypeMirrorConversionsTest, FieldTypeMirrorConversions) {
EXPECT_EQ(test_data.server_field, server_field);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AddressI18nTest,
FieldTypeMirrorConversionsTest,
testing::Values(
@@ -108,17 +108,17 @@ TEST_P(FieldTypeUnidirectionalConversionsTest,
EXPECT_EQ(test_data.expected_address_field, actual_address_field);
}
-INSTANTIATE_TEST_CASE_P(AddressI18nTest,
- FieldTypeUnidirectionalConversionsTest,
- testing::Values(
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_BILLING_LINE1, STREET_ADDRESS},
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_BILLING_LINE2, STREET_ADDRESS},
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_HOME_LINE1, STREET_ADDRESS},
- FieldTypeUnidirectionalConversionsTestCase{
- ADDRESS_HOME_LINE2, STREET_ADDRESS}));
+INSTANTIATE_TEST_SUITE_P(AddressI18nTest,
+ FieldTypeUnidirectionalConversionsTest,
+ testing::Values(
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_BILLING_LINE1, STREET_ADDRESS},
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_BILLING_LINE2, STREET_ADDRESS},
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_HOME_LINE1, STREET_ADDRESS},
+ FieldTypeUnidirectionalConversionsTestCase{
+ ADDRESS_HOME_LINE2, STREET_ADDRESS}));
TEST(AddressI18nTest, UnconvertableServerFields) {
EXPECT_FALSE(FieldForType(PHONE_HOME_NUMBER, nullptr));
diff --git a/chromium/components/autofill/core/browser/autocomplete_history_manager.cc b/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
index d15eb19251a..8eae19020de 100644
--- a/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
+++ b/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
diff --git a/chromium/components/autofill/core/browser/autofill_assistant.cc b/chromium/components/autofill/core/browser/autofill_assistant.cc
index d72104c0909..5cbbd241c0b 100644
--- a/chromium/components/autofill/core/browser/autofill_assistant.cc
+++ b/chromium/components/autofill/core/browser/autofill_assistant.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/autofill_assistant.h"
+#include "base/bind.h"
#include "base/containers/adapters.h"
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_manager.h"
diff --git a/chromium/components/autofill/core/browser/autofill_client.h b/chromium/components/autofill/core/browser/autofill_client.h
index cb53a600e65..0341ce2c565 100644
--- a/chromium/components/autofill/core/browser/autofill_client.h
+++ b/chromium/components/autofill/core/browser/autofill_client.h
@@ -123,6 +123,35 @@ class AutofillClient : public RiskDataLoader {
base::string16 expiration_date_year;
};
+ // Used for options of upload prompt.
+ struct SaveCreditCardOptions {
+ SaveCreditCardOptions& with_has_non_focusable_field(bool b) {
+ has_non_focusable_field = b;
+ return *this;
+ }
+
+ SaveCreditCardOptions& with_should_request_name_from_user(bool b) {
+ should_request_name_from_user = b;
+ return *this;
+ }
+
+ SaveCreditCardOptions& with_should_request_expiration_date_from_user(
+ bool b) {
+ should_request_expiration_date_from_user = b;
+ return *this;
+ }
+
+ SaveCreditCardOptions& with_show_prompt(bool b = true) {
+ show_prompt = b;
+ return *this;
+ }
+
+ bool has_non_focusable_field = false;
+ bool should_request_name_from_user = false;
+ bool should_request_expiration_date_from_user = false;
+ bool show_prompt = false;
+ };
+
// Callback to run after local credit card save is offered. Sends whether the
// prompt was accepted, declined, or ignored in |user_decision|.
typedef base::OnceCallback<void(SaveCardOfferUserDecision user_decision)>
@@ -247,35 +276,43 @@ class AutofillClient : public RiskDataLoader {
// Runs |callback| once the user makes a decision with respect to the
// offer-to-save prompt. On desktop, shows the offer-to-save bubble if
- // |show_prompt| is true; otherwise only shows the omnibox icon. On mobile,
- // shows the offer-to-save infobar if |show_prompt| is true; otherwise does
- // not offer to save at all.
+ // |options.show_prompt| is true; otherwise only shows the
+ // omnibox icon. On mobile, shows the offer-to-save infobar if
+ // |options.show_prompt| is true; otherwise does not offer to
+ // save at all.
virtual void ConfirmSaveCreditCardLocally(
const CreditCard& card,
- bool show_prompt,
+ AutofillClient::SaveCreditCardOptions options,
LocalSaveCardPromptCallback callback) = 0;
#if defined(OS_ANDROID)
- // Run |callback| if the card should be uploaded to payments with updated
- // name from the user.
+ // Display the cardholder name fix flow prompt and run the |callback| if
+ // the card should be uploaded to payments with updated name from the user.
virtual void ConfirmAccountNameFixFlow(
base::OnceCallback<void(const base::string16&)> callback) = 0;
+ // Display the expiration date fix flow prompt with the |card| details
+ // and run the |callback| if the card should be uploaded to payments with
+ // updated expiration date from the user.
+ virtual void ConfirmExpirationDateFixFlow(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ callback) = 0;
#endif // defined(OS_ANDROID)
// Runs |callback| once the user makes a decision with respect to the
// offer-to-save prompt. Displays the contents of |legal_message| to the user.
// Displays a cardholder name textfield in the bubble if
- // |should_request_name_from_user| is true. Displays a pair of expiration date
- // dropdowns in the bubble if |should_request_expiration_date_from_user| is
- // true. On desktop, shows the offer-to-save bubble if |show_prompt| is true;
+ // |options.should_request_name_from_user| is true. Displays
+ // a pair of expiration date dropdowns in the bubble if
+ // |should_request_expiration_date_from_user| is true. On desktop, shows the
+ // offer-to-save bubble if |options.show_prompt| is true;
// otherwise only shows the omnibox icon. On mobile, shows the offer-to-save
- // infobar if |show_prompt| is true; otherwise does not offer to save at all.
+ // infobar if |options.show_prompt| is true; otherwise does
+ // not offer to save at all.
virtual void ConfirmSaveCreditCardToCloud(
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- bool should_request_name_from_user,
- bool should_request_expiration_date_from_user,
- bool show_prompt,
+ SaveCreditCardOptions options,
UploadSaveCardPromptCallback callback) = 0;
// Will show an infobar to get user consent for Credit Card assistive filling.
diff --git a/chromium/components/autofill/core/browser/autofill_data_model.cc b/chromium/components/autofill/core/browser/autofill_data_model.cc
index 913bfe22e69..59f83e57b3e 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_model.cc
@@ -37,8 +37,9 @@ bool AutofillDataModel::UseDateEqualsInSeconds(
return !((other->use_date() - use_date()).InSeconds());
}
-bool AutofillDataModel::CompareFrecency(const AutofillDataModel* other,
- base::Time comparison_time) const {
+bool AutofillDataModel::HasGreaterFrecencyThan(
+ const AutofillDataModel* other,
+ base::Time comparison_time) const {
double score = GetFrecencyScore(comparison_time);
double other_score = other->GetFrecencyScore(comparison_time);
@@ -79,4 +80,15 @@ bool AutofillDataModel::IsDeletable() const {
return use_date_ < AutofillClock::Now() - kDisusedDataModelDeletionTimeDelta;
}
+AutofillDataModel::ValidityState AutofillDataModel::GetValidityState(
+ ServerFieldType type,
+ AutofillDataModel::ValidationSource source) const {
+ return AutofillDataModel::UNSUPPORTED;
+}
+
+bool AutofillDataModel::ShouldSkipFillingOrSuggesting(
+ ServerFieldType type) const {
+ return false;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_data_model.h b/chromium/components/autofill/core/browser/autofill_data_model.h
index 719df504e04..07fd92b828d 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model.h
+++ b/chromium/components/autofill/core/browser/autofill_data_model.h
@@ -22,6 +22,26 @@ struct AutofillMetadata;
// PersonalDataManager.
class AutofillDataModel : public FormGroup {
public:
+ enum ValidityState {
+ // The field has not been validated.
+ UNVALIDATED = 0,
+ // The field is empty.
+ EMPTY = 1,
+ // The field is valid.
+ VALID = 2,
+ // The field is invalid.
+ INVALID = 3,
+ // The validation for the field is unsupported.
+ UNSUPPORTED = 4,
+ };
+
+ enum ValidationSource {
+ // The validity state is according to the client validation.
+ CLIENT = 0,
+ // The validity state is according to the server validation.
+ SERVER = 1,
+ };
+
AutofillDataModel(const std::string& guid, const std::string& origin);
~AutofillDataModel() override;
@@ -56,8 +76,8 @@ class AutofillDataModel : public FormGroup {
// a combination of frequency and recency to determine the relevance of the
// profile. |comparison_time_| allows consistent sorting throughout the
// comparisons.
- bool CompareFrecency(const AutofillDataModel* other,
- base::Time comparison_time) const;
+ bool HasGreaterFrecencyThan(const AutofillDataModel* other,
+ base::Time comparison_time) const;
// Gets the metadata associated with this autofill data model.
virtual AutofillMetadata GetMetadata() const;
@@ -70,6 +90,14 @@ class AutofillDataModel : public FormGroup {
// longer than |kDisusedCreditCardDeletionTimeDelta|.
virtual bool IsDeletable() const;
+ // Returns the validity state of the specified autofill type.
+ virtual ValidityState GetValidityState(ServerFieldType type,
+ ValidationSource source) const;
+
+ // Check for the validity of the data. Leave the field empty if the data is
+ // invalid and the relevant feature is enabled.
+ virtual bool ShouldSkipFillingOrSuggesting(ServerFieldType type) const;
+
protected:
// Called to update |use_count_| and |use_date_| when this data model is
// the subject of user interaction (usually, when it's used to fill a form).
diff --git a/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc b/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc
index 670e50ce8d1..f719d9b7ac7 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_model_unittest.cc
@@ -110,7 +110,7 @@ TEST(AutofillDataModelTest, IsDeletable) {
}
enum Expectation { GREATER, LESS };
-struct CompareFrecencyTestCase {
+struct HasGreaterFrecencyThanTestCase {
const std::string guid_a;
const int use_count_a;
const base::Time use_date_a;
@@ -122,10 +122,10 @@ struct CompareFrecencyTestCase {
base::Time now = base::Time::Now();
-class CompareFrecencyTest
- : public testing::TestWithParam<CompareFrecencyTestCase> {};
+class HasGreaterFrecencyThanTest
+ : public testing::TestWithParam<HasGreaterFrecencyThanTestCase> {};
-TEST_P(CompareFrecencyTest, CompareFrecency) {
+TEST_P(HasGreaterFrecencyThanTest, HasGreaterFrecencyThan) {
auto test_case = GetParam();
TestAutofillDataModel model_a(test_case.guid_a, test_case.use_count_a,
test_case.use_date_a);
@@ -133,39 +133,44 @@ TEST_P(CompareFrecencyTest, CompareFrecency) {
test_case.use_date_b);
EXPECT_EQ(test_case.expectation == GREATER,
- model_a.CompareFrecency(&model_b, now));
+ model_a.HasGreaterFrecencyThan(&model_b, now));
EXPECT_NE(test_case.expectation == GREATER,
- model_b.CompareFrecency(&model_a, now));
+ model_b.HasGreaterFrecencyThan(&model_a, now));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataModelTest,
- CompareFrecencyTest,
+ HasGreaterFrecencyThanTest,
testing::Values(
// Same frecency, model_a has a smaller GUID (tie breaker).
- CompareFrecencyTestCase{"guid_a", 8, now, "guid_b", 8, now, LESS},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8, now, "guid_b", 8, now,
+ LESS},
// Same recency, model_a has a bigger frequency.
- CompareFrecencyTestCase{"guid_a", 10, now, "guid_b", 8, now, GREATER},
+ HasGreaterFrecencyThanTestCase{"guid_a", 10, now, "guid_b", 8, now,
+ GREATER},
// Same recency, model_a has a smaller frequency.
- CompareFrecencyTestCase{"guid_a", 8, now, "guid_b", 10, now, LESS},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8, now, "guid_b", 10, now,
+ LESS},
// Same frequency, model_a is more recent.
- CompareFrecencyTestCase{"guid_a", 8, now, "guid_b", 8,
- now - base::TimeDelta::FromDays(1), GREATER},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8, now, "guid_b", 8,
+ now - base::TimeDelta::FromDays(1),
+ GREATER},
// Same frequency, model_a is less recent.
- CompareFrecencyTestCase{"guid_a", 8, now - base::TimeDelta::FromDays(1),
- "guid_b", 8, now, LESS},
+ HasGreaterFrecencyThanTestCase{"guid_a", 8,
+ now - base::TimeDelta::FromDays(1),
+ "guid_b", 8, now, LESS},
// Special case: occasional profiles. A profile with relatively low
// usage and used recently (model_b) should not rank higher than a more
// used profile that has been unused for a short amount of time
// (model_a).
- CompareFrecencyTestCase{
+ HasGreaterFrecencyThanTestCase{
"guid_a", 300, now - base::TimeDelta::FromDays(5), "guid_b", 10,
now - base::TimeDelta::FromDays(1), GREATER},
// Special case: moving. A new profile used frequently (model_b) should
// rank higher than a profile with more usage that has not been used for
// a while (model_a).
- CompareFrecencyTestCase{"guid_a", 300,
- now - base::TimeDelta::FromDays(15), "guid_b",
- 10, now - base::TimeDelta::FromDays(1), LESS}));
+ HasGreaterFrecencyThanTestCase{
+ "guid_a", 300, now - base::TimeDelta::FromDays(15), "guid_b", 10,
+ now - base::TimeDelta::FromDays(1), LESS}));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc b/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
index d2de5151ec8..57c7748b217 100644
--- a/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_util_unittest.cc
@@ -25,7 +25,7 @@ TEST_P(IsCJKNameTest, IsCJKName) {
<< "Failed for: " << test_case.full_name;
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtilTest,
IsCJKNameTest,
testing::Values(
@@ -73,7 +73,7 @@ TEST_P(SplitNameTest, SplitName) {
EXPECT_EQ(base::UTF8ToUTF16(test_case.family_name), name_parts.family);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtil,
SplitNameTest,
testing::Values(
@@ -150,7 +150,7 @@ TEST_P(JoinNamePartsTest, JoinNameParts) {
EXPECT_EQ(base::UTF8ToUTF16(test_case.full_name), joined);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtil,
JoinNamePartsTest,
testing::Values(
@@ -213,7 +213,7 @@ TEST_P(ValidCountryCodeTest, ValidCountryCode) {
IsValidCountryCode(test_case.country_code));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillDataUtil,
ValidCountryCodeTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/autofill_download_manager.cc b/chromium/components/autofill/core/browser/autofill_download_manager.cc
index adeb0145dd7..1b9a0429dd4 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager.cc
+++ b/chromium/components/autofill/core/browser/autofill_download_manager.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/autofill_download_manager.h"
+#include <algorithm>
#include <tuple>
#include <utility>
@@ -34,6 +35,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/submission_source.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
+#include "components/google/core/common/google_util.h"
#include "components/history/core/browser/history_service.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
@@ -52,6 +54,12 @@ namespace autofill {
namespace {
+// The reserved identifier ranges for autofill server experiments.
+constexpr std::pair<int, int> kAutofillExperimentRanges[] = {
+ {3312923, 3312930}, {3314208, 3314209}, {3314711, 3314712},
+ {3314445, 3314448}, {3314854, 3314883},
+};
+
const size_t kMaxQueryGetSize = 1400; // 1.25KB
const size_t kAutofillDownloadManagerMaxFormCacheSize = 16;
const size_t kMaxFieldsPerQueryRequest = 100;
@@ -85,6 +93,13 @@ const net::BackoffEntry::Policy kAutofillBackoffPolicy = {
const char kDefaultAutofillServerURL[] =
"https://clients1.google.com/tbproxy/af/";
+// The default number of days after which to reset the registry of autofill
+// events for which an upload has been sent.
+constexpr base::FeatureParam<int> kAutofillUploadThrottlingPeriodInDays(
+ &features::kAutofillUploadThrottling,
+ switches::kAutofillUploadThrottlingPeriodInDays,
+ 28);
+
// Header for API key.
constexpr char kGoogApiKey[] = "X-Goog-Api-Key";
// Header to get base64 encoded serialized proto from API for safety.
@@ -93,6 +108,12 @@ constexpr char kGoogEncodeResponseIfExecutable[] =
constexpr char kDefaultAPIKey[] = "";
+// The maximum number of attempts for a given autofill request.
+constexpr base::FeatureParam<int> kAutofillMaxServerAttempts(
+ &features::kAutofillServerCommunication,
+ "max-attempts",
+ 5);
+
// Returns the base URL for the autofill server.
GURL GetAutofillServerURL() {
// If a valid autofill server URL is specified on the command line, then the
@@ -136,6 +157,20 @@ GURL GetAutofillServerURL() {
return autofill_server_url;
}
+base::TimeDelta GetThrottleResetPeriod() {
+ return base::TimeDelta::FromDays(
+ std::max(1, kAutofillUploadThrottlingPeriodInDays.Get()));
+}
+
+// Returns true if |id| is within |kAutofillExperimentRanges|.
+bool IsAutofillExperimentId(int id) {
+ for (const auto& range : kAutofillExperimentRanges) {
+ if (range.first <= id && id <= range.second)
+ return true;
+ }
+ return false;
+}
+
// Helper to log the HTTP |response_code| and other data received for
// |request_type| to UMA.
void LogHttpResponseData(AutofillDownloadManager::RequestType request_type,
@@ -343,21 +378,24 @@ std::ostream& operator<<(std::ostream& out,
return out;
}
-// Check for and returns true if |upload_event| is allowed to trigger an upload
-// for |form|. If true, updates |prefs| to track that |upload_event| has been
-// recorded for |form|.
-bool IsUploadAllowed(const FormStructure& form, PrefService* pref_service) {
- if (!pref_service ||
- !base::FeatureList::IsEnabled(features::kAutofillUploadThrottling)) {
- return true;
- }
+// Returns true if an upload of |form| triggered by |form.submission_source()|
+// can be throttled/suppressed. This is true if |prefs| indicates that this
+// upload has already happened within the last update window. Updates |prefs|
+// account for the upload for |form|.
+bool CanThrottleUpload(const FormStructure& form,
+ base::TimeDelta throttle_reset_period,
+ PrefService* pref_service) {
+ // PasswordManager uploads are triggered via specific first occurrences and
+ // do not participate in the pref-service tracked throttling mechanism. Return
+ // false for these uploads.
+ if (!pref_service)
+ return false;
// If the upload event pref needs to be reset, clear it now.
- static constexpr base::TimeDelta kResetPeriod = base::TimeDelta::FromDays(28);
base::Time now = AutofillClock::Now();
base::Time last_reset =
pref_service->GetTime(prefs::kAutofillUploadEventsLastResetTimestamp);
- if ((now - last_reset) > kResetPeriod) {
+ if ((now - last_reset) > throttle_reset_period) {
AutofillDownloadManager::ClearUploadHistory(pref_service);
}
@@ -376,17 +414,15 @@ bool IsUploadAllowed(const FormStructure& form, PrefService* pref_service) {
DCHECK_LT(bit, 32);
const int mask = (1 << bit);
- // Check if the upload should be allowed and, if so, update the upload event
- // pref to set the appropriate bit.
- bool allow_upload = ((value & mask) == 0);
- if (allow_upload) {
+ // Check if this is the first upload for this event. If so, update the upload
+ // event pref to set the appropriate bit.
+ bool is_first_upload_for_event = ((value & mask) == 0);
+ if (is_first_upload_for_event) {
DictionaryPrefUpdate update(pref_service, prefs::kAutofillUploadEvents);
update->SetKey(std::move(key), base::Value(value | mask));
}
- // Capture metrics and return.
- AutofillMetrics::LogUploadEvent(form.submission_source(), allow_upload);
- return allow_upload;
+ return !is_first_upload_for_event;
}
// Determines whether to use the API instead of the legacy server.
@@ -441,8 +477,20 @@ struct AutofillDownloadManager::FormRequestData {
std::vector<std::string> form_signatures;
RequestType request_type;
std::string payload;
+ int num_attempts = 0;
};
+ScopedActiveAutofillExperiments::ScopedActiveAutofillExperiments() {
+ AutofillDownloadManager::ResetActiveExperiments();
+}
+
+ScopedActiveAutofillExperiments::~ScopedActiveAutofillExperiments() {
+ AutofillDownloadManager::ResetActiveExperiments();
+}
+
+std::vector<variations::VariationID>*
+ AutofillDownloadManager::active_experiments_ = nullptr;
+
AutofillDownloadManager::AutofillDownloadManager(AutofillDriver* driver,
Observer* observer,
const std::string& api_key)
@@ -450,6 +498,7 @@ AutofillDownloadManager::AutofillDownloadManager(AutofillDriver* driver,
observer_(observer),
api_key_(api_key),
autofill_server_url_(GetAutofillServerURL()),
+ throttle_reset_period_(GetThrottleResetPeriod()),
max_form_cache_size_(kAutofillDownloadManagerMaxFormCacheSize),
loader_backoff_(&kAutofillBackoffPolicy),
weak_factory_(this) {
@@ -472,6 +521,7 @@ bool AutofillDownloadManager::StartQueryRequest(
if (CountActiveFieldsInForms(forms) > kMaxFieldsPerQueryRequest)
return false;
+ // Encode the query for the requested forms.
AutofillQueryContents query;
FormRequestData request_data;
if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures,
@@ -479,6 +529,17 @@ bool AutofillDownloadManager::StartQueryRequest(
return false;
}
+ // The set of active autofill experiments is constant for the life of the
+ // process. We initialize and statically cache it on first use. Leaked on
+ // process termination.
+ if (active_experiments_ == nullptr)
+ InitActiveExperiments();
+
+ // Attach any active autofill experiments.
+ query.mutable_experiments()->Reserve(active_experiments_->size());
+ for (int id : *active_experiments_)
+ query.mutable_experiments()->Add(id);
+
// Get the query request payload.
std::string payload;
bool is_payload_serialized =
@@ -515,7 +576,18 @@ bool AutofillDownloadManager::StartUploadRequest(
const std::string& login_form_signature,
bool observed_submission,
PrefService* prefs) {
- if (!IsEnabled() || !IsUploadAllowed(form, prefs))
+ if (!IsEnabled())
+ return false;
+
+ bool can_throttle_upload =
+ CanThrottleUpload(form, throttle_reset_period_, prefs);
+ bool throttling_is_enabled =
+ base::FeatureList::IsEnabled(features::kAutofillUploadThrottling);
+ bool is_small_form = form.active_field_count() < 3;
+ bool allow_upload =
+ !(can_throttle_upload && (throttling_is_enabled || is_small_form));
+ AutofillMetrics::LogUploadEvent(form.submission_source(), allow_upload);
+ if (!allow_upload)
return false;
AutofillUploadContents upload;
@@ -525,6 +597,18 @@ bool AutofillDownloadManager::StartUploadRequest(
return false;
}
+ // If this upload was a candidate for throttling, tag it and make sure that
+ // any throttling sensitive features are enforced.
+ if (can_throttle_upload) {
+ upload.set_was_throttleable(true);
+
+ // Don't send randomized metadata.
+ upload.clear_randomized_form_metadata();
+ for (auto& f : *upload.mutable_field()) {
+ f.clear_randomized_field_metadata();
+ }
+ }
+
// Get the POST payload that contains upload data.
std::string payload;
bool is_payload = UseApi() ? GetUploadPayloadForApi(upload, &payload)
@@ -637,11 +721,11 @@ bool AutofillDownloadManager::StartRequest(FormRequestData request_data) {
resource_request->method = method;
// Add Chrome experiment state to the request headers.
- variations::AppendVariationHeadersUnknownSignedIn(
+ variations::AppendVariationsHeaderUnknownSignedIn(
request_url,
driver_->IsIncognito() ? variations::InIncognito::kYes
: variations::InIncognito::kNo,
- &resource_request->headers);
+ resource_request.get());
// Set headers specific to the API if using it.
if (UseApi())
@@ -649,10 +733,10 @@ bool AutofillDownloadManager::StartRequest(FormRequestData request_data) {
resource_request->headers.SetHeader(kGoogEncodeResponseIfExecutable,
"base64");
- // Put API key in request's header if there is.
- if (!api_key_.empty() &&
- variations::ShouldAppendVariationHeaders(request_url)) {
- // Make sure that we only send the API key to endpoints trusted by Chrome.
+ // Put API key in request's header if a key exists, and the endpoint is
+ // trusted by Google.
+ if (!api_key_.empty() && request_url.SchemeIs(url::kHttpsScheme) &&
+ google_util::IsGoogleAssociatedDomainUrl(request_url)) {
resource_request->headers.SetHeader(kGoogApiKey, api_key_);
}
@@ -738,6 +822,16 @@ std::string AutofillDownloadManager::GetCombinedSignature(
return signature;
}
+// static
+int AutofillDownloadManager::GetMaxServerAttempts() {
+ // This value is constant for the life of the browser, so we cache it
+ // statically on first use to avoid re-parsing the param on each retry
+ // opportunity. The range is forced to be within [1, 20].
+ static int max_attempts =
+ std::max(1, std::min(20, kAutofillMaxServerAttempts.Get()));
+ return max_attempts;
+}
+
void AutofillDownloadManager::OnSimpleLoaderComplete(
std::list<std::unique_ptr<network::SimpleURLLoader>>::iterator it,
FormRequestData request_data,
@@ -786,6 +880,10 @@ void AutofillDownloadManager::OnSimpleLoaderComplete(
if (response_code >= 400 && response_code <= 499)
return;
+ // If we've exhausted the maximum number of attempts, don't retry.
+ if (++request_data.num_attempts >= GetMaxServerAttempts())
+ return;
+
base::TimeDelta backoff = loader_backoff_.GetTimeUntilRelease();
LogExponentialBackoffDelay(request_data.request_type, backoff);
@@ -815,4 +913,25 @@ void AutofillDownloadManager::OnSimpleLoaderComplete(
observer_->OnUploadedPossibleFieldTypes();
}
+void AutofillDownloadManager::InitActiveExperiments() {
+ auto* variations_http_header_provider =
+ variations::VariationsHttpHeaderProvider::GetInstance();
+ DCHECK(variations_http_header_provider != nullptr);
+
+ delete active_experiments_;
+ active_experiments_ = new std::vector<variations::VariationID>(
+ variations_http_header_provider->GetVariationsVector(
+ variations::GOOGLE_WEB_PROPERTIES_TRIGGER));
+ base::EraseIf(*active_experiments_, [](variations::VariationID id) {
+ return !IsAutofillExperimentId(id);
+ });
+ std::sort(active_experiments_->begin(), active_experiments_->end());
+}
+
+// static
+void AutofillDownloadManager::ResetActiveExperiments() {
+ delete active_experiments_;
+ active_experiments_ = nullptr;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_download_manager.h b/chromium/components/autofill/core/browser/autofill_download_manager.h
index ae7a8a988b2..f38c3ae8218 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager.h
+++ b/chromium/components/autofill/core/browser/autofill_download_manager.h
@@ -19,6 +19,7 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_type.h"
+#include "components/variations/variations_http_header_provider.h"
#include "net/base/backoff_entry.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"
@@ -30,6 +31,13 @@ namespace autofill {
class AutofillDriver;
class FormStructure;
+// A helper to make sure that tests which modify the set of active autofill
+// experiments do not interfere with one another.
+struct ScopedActiveAutofillExperiments {
+ ScopedActiveAutofillExperiments();
+ ~ScopedActiveAutofillExperiments();
+};
+
// Handles getting and updating Autofill heuristics.
class AutofillDownloadManager {
public:
@@ -108,9 +116,12 @@ class AutofillDownloadManager {
private:
friend class AutofillDownloadManagerTest;
+ friend struct ScopedActiveAutofillExperiments;
FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, QueryAndUploadTest);
FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, BackoffLogic_Upload);
FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, BackoffLogic_Query);
+ FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, RetryLimit_Upload);
+ FRIEND_TEST_ALL_PREFIXES(AutofillDownloadManagerTest, RetryLimit_Query);
struct FormRequestData;
typedef std::list<std::pair<std::string, std::string> > QueryRequestCache;
@@ -151,12 +162,18 @@ class AutofillDownloadManager {
std::string GetCombinedSignature(
const std::vector<std::string>& forms_in_query) const;
+ // Returns the maximum number of attempts for a given autofill server request.
+ static int GetMaxServerAttempts();
+
void OnSimpleLoaderComplete(
std::list<std::unique_ptr<network::SimpleURLLoader>>::iterator it,
FormRequestData request_data,
base::TimeTicks request_start,
std::unique_ptr<std::string> response_body);
+ static void InitActiveExperiments();
+ static void ResetActiveExperiments();
+
// The AutofillDriver that this instance will use. Must not be null, and must
// outlive this instance.
AutofillDriver* const driver_; // WEAK
@@ -172,6 +189,12 @@ class AutofillDownloadManager {
// final path component for the request and the query params.
const GURL autofill_server_url_;
+ // The period after which the tracked set of uploads to throttle is reset.
+ const base::TimeDelta throttle_reset_period_;
+
+ // The set of active autofill server experiments.
+ static std::vector<variations::VariationID>* active_experiments_;
+
// Loaders used for the processing the requests. Invalidated after completion.
std::list<std::unique_ptr<network::SimpleURLLoader>> url_loaders_;
diff --git a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
index 13d7f760d5c..9e23fc158a4 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -38,6 +38,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/form_data.h"
#include "components/prefs/pref_service.h"
+#include "components/variations/variations_http_header_provider.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
@@ -127,7 +128,7 @@ bool GetUploadRequestProtoFromRequest(
// The responses in test are out of order and verify: successful query request,
// successful upload request, failed upload request.
class AutofillDownloadManagerTest : public AutofillDownloadManager::Observer,
- public testing::Test {
+ public ::testing::Test {
public:
AutofillDownloadManagerTest()
: test_shared_loader_factory_(
@@ -186,6 +187,7 @@ class AutofillDownloadManagerTest : public AutofillDownloadManager::Observer,
ResponseData() : type_of_response(REQUEST_QUERY_FAILED), error(0) {}
};
+ ScopedActiveAutofillExperiments scoped_active_autofill_experiments;
base::test::ScopedTaskEnvironment task_environment_;
std::list<ResponseData> responses_;
scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
@@ -766,6 +768,163 @@ TEST_F(AutofillDownloadManagerTest, BackoffLogic_Upload) {
EXPECT_EQ(1, buckets[0].count);
}
+TEST_F(AutofillDownloadManagerTest, RetryLimit_Query) {
+ FormData form;
+ FormFieldData field;
+ field.label = UTF8ToUTF16("address");
+ field.name = UTF8ToUTF16("address");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("address2");
+ field.name = UTF8ToUTF16("address2");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("city");
+ field.name = UTF8ToUTF16("city");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = base::string16();
+ field.name = UTF8ToUTF16("Submit");
+ field.form_control_type = "submit";
+ form.fields.push_back(field);
+
+ std::vector<std::unique_ptr<FormStructure>> form_structures;
+ form_structures.push_back(std::make_unique<FormStructure>(form));
+
+ // Request with id 0.
+ base::HistogramTester histogram;
+ EXPECT_TRUE(
+ download_manager_.StartQueryRequest(ToRawPointerVector(form_structures)));
+ histogram.ExpectUniqueSample("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+
+ const auto kTimeDeltaMargin = base::TimeDelta::FromMilliseconds(100);
+ const int max_attempts = download_manager_.GetMaxServerAttempts();
+ int attempt = 0;
+ while (true) {
+ auto* request = test_url_loader_factory_.GetPendingRequest(attempt);
+ ASSERT_TRUE(request != nullptr);
+
+ // Request error incurs a retry after 1 second.
+ test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
+ request,
+ network::CreateResourceResponseHead(net::HTTP_INTERNAL_SERVER_ERROR),
+ "<html></html>", network::URLLoaderCompletionStatus(net::OK));
+
+ EXPECT_EQ(1U, responses_.size());
+ const auto& response = responses_.front();
+ EXPECT_EQ(AutofillDownloadManagerTest::REQUEST_QUERY_FAILED,
+ response.type_of_response);
+ EXPECT_EQ(net::HTTP_INTERNAL_SERVER_ERROR, response.error);
+ responses_.pop_front();
+
+ if (++attempt >= max_attempts)
+ break;
+
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ download_manager_.loader_backoff_.GetTimeUntilRelease() +
+ kTimeDeltaMargin);
+ run_loop.Run();
+ }
+
+ // There should not be an additional retry.
+ EXPECT_EQ(attempt, max_attempts);
+ EXPECT_EQ(nullptr, test_url_loader_factory_.GetPendingRequest(attempt));
+ EXPECT_EQ(test_url_loader_factory_.NumPending(), 0);
+
+ // Verify metrics.
+ histogram.ExpectBucketCount("Autofill.Query.HttpResponseOrErrorCode",
+ net::HTTP_INTERNAL_SERVER_ERROR, max_attempts);
+ auto buckets = histogram.GetAllSamples("Autofill.Query.FailingPayloadSize");
+ ASSERT_EQ(1U, buckets.size());
+ EXPECT_EQ(max_attempts, buckets[0].count);
+}
+
+TEST_F(AutofillDownloadManagerTest, RetryLimit_Upload) {
+ FormData form;
+ FormFieldData field;
+ field.label = UTF8ToUTF16("address");
+ field.name = UTF8ToUTF16("address");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("address2");
+ field.name = UTF8ToUTF16("address2");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = UTF8ToUTF16("city");
+ field.name = UTF8ToUTF16("city");
+ field.form_control_type = "text";
+ form.fields.push_back(field);
+
+ field.label = base::string16();
+ field.name = UTF8ToUTF16("Submit");
+ field.form_control_type = "submit";
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram;
+ const auto kTimeDeltaMargin = base::TimeDelta::FromMilliseconds(100);
+
+ auto form_structure = std::make_unique<FormStructure>(form);
+ form_structure->set_submission_source(SubmissionSource::FORM_SUBMISSION);
+
+ // Request with id 0.
+ EXPECT_TRUE(download_manager_.StartUploadRequest(
+ *form_structure, true, ServerFieldTypeSet(), std::string(), true,
+ pref_service_.get()));
+
+ const int max_attempts = download_manager_.GetMaxServerAttempts();
+ int attempt = 0;
+ while (true) {
+ auto* request = test_url_loader_factory_.GetPendingRequest(attempt);
+ ASSERT_TRUE(request != nullptr);
+
+ // Simulate a server failure.
+ test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
+ request,
+ network::CreateResourceResponseHead(net::HTTP_INTERNAL_SERVER_ERROR),
+ "", network::URLLoaderCompletionStatus(net::OK));
+
+ // Check that it was a failure.
+ ASSERT_EQ(1U, responses_.size());
+ const auto& response = responses_.front();
+ EXPECT_EQ(AutofillDownloadManagerTest::REQUEST_UPLOAD_FAILED,
+ response.type_of_response);
+ EXPECT_EQ(net::HTTP_INTERNAL_SERVER_ERROR, response.error);
+ responses_.pop_front();
+
+ if (++attempt >= max_attempts)
+ break;
+
+ // A retry should have been scheduled with wait time on the order of
+ // |delay|.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ download_manager_.loader_backoff_.GetTimeUntilRelease() +
+ kTimeDeltaMargin);
+ run_loop.Run();
+ }
+
+ // There should not be an additional retry.
+ EXPECT_EQ(attempt, max_attempts);
+ EXPECT_EQ(nullptr, test_url_loader_factory_.GetPendingRequest(attempt));
+ EXPECT_EQ(test_url_loader_factory_.NumPending(), 0);
+
+ // Verify metrics.
+ histogram.ExpectBucketCount("Autofill.Upload.HttpResponseOrErrorCode",
+ net::HTTP_INTERNAL_SERVER_ERROR, max_attempts);
+ auto buckets = histogram.GetAllSamples("Autofill.Upload.FailingPayloadSize");
+ ASSERT_EQ(1U, buckets.size());
+ EXPECT_EQ(max_attempts, buckets[0].count);
+}
+
TEST_F(AutofillDownloadManagerTest, QueryTooManyFieldsTest) {
// Create a query that contains too many fields for the server.
std::vector<FormData> forms(21);
@@ -773,8 +932,8 @@ TEST_F(AutofillDownloadManagerTest, QueryTooManyFieldsTest) {
for (auto& form : forms) {
for (size_t i = 0; i < 5; ++i) {
FormFieldData field;
- field.label = base::IntToString16(i);
- field.name = base::IntToString16(i);
+ field.label = base::NumberToString16(i);
+ field.name = base::NumberToString16(i);
field.form_control_type = "text";
form.fields.push_back(field);
}
@@ -794,8 +953,8 @@ TEST_F(AutofillDownloadManagerTest, QueryNotTooManyFieldsTest) {
for (auto& form : forms) {
for (size_t i = 0; i < 4; ++i) {
FormFieldData field;
- field.label = base::IntToString16(i);
- field.name = base::IntToString16(i);
+ field.label = base::NumberToString16(i);
+ field.name = base::NumberToString16(i);
field.form_control_type = "text";
form.fields.push_back(field);
}
@@ -1024,6 +1183,11 @@ class AutofillServerCommunicationTest
void TearDown() override {
if (server_.Started())
ASSERT_TRUE(server_.ShutdownAndWaitUntilComplete());
+
+ auto* variations_http_header_provider =
+ variations::VariationsHttpHeaderProvider::GetInstance();
+ if (variations_http_header_provider != nullptr)
+ variations_http_header_provider->ResetForTesting();
}
// AutofillDownloadManager::Observer implementation.
@@ -1098,6 +1262,7 @@ class AutofillServerCommunicationTest
EXPECT_EQ(run_loop_, nullptr);
run_loop_ = std::make_unique<base::RunLoop>();
+ ScopedActiveAutofillExperiments scoped_active_autofill_experiments;
AutofillDownloadManager download_manager(driver_.get(), this);
bool succeeded =
download_manager.StartQueryRequest(ToRawPointerVector(form_structures));
@@ -1115,6 +1280,7 @@ class AutofillServerCommunicationTest
EXPECT_EQ(run_loop_, nullptr);
run_loop_ = std::make_unique<base::RunLoop>();
+ ScopedActiveAutofillExperiments scoped_active_autofill_experiments;
AutofillDownloadManager download_manager(driver_.get(), this);
bool succeeded = download_manager.StartUploadRequest(
form, form_was_autofilled, available_field_types, login_form_signature,
@@ -1188,11 +1354,11 @@ TEST_P(AutofillServerCommunicationTest, Upload) {
// Note that we omit DEFAULT_URL from the test params. We don't actually want
// the tests to hit the production server.
-INSTANTIATE_TEST_CASE_P(All,
- AutofillServerCommunicationTest,
- ::testing::Values(DISABLED,
- FINCHED_URL,
- COMMAND_LINE_URL));
+INSTANTIATE_TEST_SUITE_P(All,
+ AutofillServerCommunicationTest,
+ ::testing::Values(DISABLED,
+ FINCHED_URL,
+ COMMAND_LINE_URL));
using AutofillQueryTest = AutofillServerCommunicationTest;
@@ -1221,8 +1387,8 @@ TEST_P(AutofillQueryTest, CacheableResponse) {
histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1);
}
- // Query again the next day. This should go to the cache, since the max-age
- // for the cached response is 2 days.
+ // Query again. This should go to the cache, since the max-age for the cached
+ // response is 2 days.
{
SCOPED_TRACE("Second Query");
base::HistogramTester histogram;
@@ -1236,6 +1402,76 @@ TEST_P(AutofillQueryTest, CacheableResponse) {
}
}
+TEST_P(AutofillQueryTest, SendsExperiment) {
+ FormFieldData field;
+ field.label = UTF8ToUTF16("First Name:");
+ field.name = UTF8ToUTF16("firstname");
+ field.form_control_type = "text";
+
+ FormData form;
+ form.fields.push_back(field);
+
+ std::vector<std::unique_ptr<FormStructure>> form_structures;
+ form_structures.push_back(std::make_unique<FormStructure>(form));
+
+ // Query for the form. This should go to the embedded server.
+ {
+ SCOPED_TRACE("First Query");
+ base::HistogramTester histogram;
+ call_count_ = 0;
+ ASSERT_TRUE(SendQueryRequest(form_structures));
+ EXPECT_EQ(1u, call_count_);
+ histogram.ExpectBucketCount("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+ histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1);
+ histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1);
+ }
+
+ // Add experiment/variation idd from the range reserved for autofill.
+ auto* variations_http_header_provider =
+ variations::VariationsHttpHeaderProvider::GetInstance();
+ ASSERT_TRUE(variations_http_header_provider != nullptr);
+ variations_http_header_provider->ForceVariationIds(
+ {"t3314883", "t3312923", "t3314885"}, // first two valid, out-of-order
+ {});
+
+ // Query again. This should go to the embedded server since it's not the same
+ // as the previously cached query.
+ {
+ SCOPED_TRACE("Second Query");
+ base::HistogramTester histogram;
+ call_count_ = 0;
+ payloads_.clear();
+ ASSERT_TRUE(SendQueryRequest(form_structures));
+ EXPECT_EQ(1u, call_count_);
+ histogram.ExpectBucketCount("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+ histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1);
+ histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_MISS, 1);
+
+ ASSERT_EQ(1u, payloads_.size());
+ AutofillQueryContents query_contents;
+ ASSERT_TRUE(query_contents.ParseFromString(payloads_[0]));
+ ASSERT_EQ(2, query_contents.experiments_size());
+ EXPECT_EQ(3312923, query_contents.experiments(0));
+ EXPECT_EQ(3314883, query_contents.experiments(1));
+ }
+
+ // Query a third time (will experiments still enabled). This should go to the
+ // cache.
+ {
+ SCOPED_TRACE("Third Query");
+ base::HistogramTester histogram;
+ call_count_ = 0;
+ ASSERT_TRUE(SendQueryRequest(form_structures));
+ EXPECT_EQ(0u, call_count_);
+ histogram.ExpectBucketCount("Autofill.ServerQueryResponse",
+ AutofillMetrics::QUERY_SENT, 1);
+ histogram.ExpectBucketCount("Autofill.Query.Method", METHOD_GET, 1);
+ histogram.ExpectBucketCount("Autofill.Query.WasInCache", CACHE_HIT, 1);
+ }
+}
+
TEST_P(AutofillQueryTest, ExpiredCacheInResponse) {
FormFieldData field;
field.label = UTF8ToUTF16("First Name:");
@@ -1468,9 +1704,9 @@ TEST_P(AutofillQueryTest, RichMetadata_Disabled) {
// Note that we omit DEFAULT_URL from the test params. We don't actually want
// the tests to hit the production server. We also excluded DISABLED, since
// these tests exercise "enabled" functionality.
-INSTANTIATE_TEST_CASE_P(All,
- AutofillQueryTest,
- ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
+INSTANTIATE_TEST_SUITE_P(All,
+ AutofillQueryTest,
+ ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
using AutofillUploadTest = AutofillServerCommunicationTest;
@@ -1622,19 +1858,29 @@ TEST_P(AutofillUploadTest, Throttling) {
TEST_P(AutofillUploadTest, ThrottlingDisabled) {
ASSERT_NE(DISABLED, GetParam());
+ base::test::ScopedFeatureList local_feature;
+ local_feature.InitWithFeatures(
+ // Enabled.
+ {},
+ // Disabled
+ {features::kAutofillUploadThrottling,
+ features::kAutofillEnforceMinRequiredFieldsForUpload});
FormData form;
+ FormData small_form;
FormFieldData field;
field.label = UTF8ToUTF16("First Name:");
field.name = UTF8ToUTF16("firstname");
field.form_control_type = "text";
form.fields.push_back(field);
+ small_form.fields.push_back(field);
field.label = UTF8ToUTF16("Last Name:");
field.name = UTF8ToUTF16("lastname");
field.form_control_type = "text";
form.fields.push_back(field);
+ small_form.fields.push_back(field);
field.label = UTF8ToUTF16("Email:");
field.name = UTF8ToUTF16("email");
@@ -1643,15 +1889,16 @@ TEST_P(AutofillUploadTest, ThrottlingDisabled) {
AutofillDownloadManager download_manager(driver_.get(), this);
FormStructure form_structure(form);
-
- base::test::ScopedFeatureList local_feature;
- local_feature.InitAndDisableFeature(features::kAutofillUploadThrottling);
+ FormStructure small_form_structure(small_form);
for (int i = 0; i < 8; ++i) {
SCOPED_TRACE(base::StringPrintf("submission source = %d", i));
base::HistogramTester histogram_tester;
auto submission_source = static_cast<SubmissionSource>(i);
form_structure.set_submission_source(submission_source);
+ small_form_structure.set_submission_source(submission_source);
+
+ payloads_.clear();
// The first attempt should succeed.
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
@@ -1662,19 +1909,45 @@ TEST_P(AutofillUploadTest, ThrottlingDisabled) {
// The third attempt should also succeed
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
- // No throttling metrics should be logged.
- EXPECT_TRUE(histogram_tester.GetAllSamples("Autofill.UploadEvent").empty());
- EXPECT_TRUE(
- histogram_tester
- .GetAllSamples(AutofillMetrics::SubmissionSourceToUploadEventMetric(
- submission_source))
- .empty());
+ // The first small form attempt should succeed
+ EXPECT_TRUE(SendUploadRequest(small_form_structure, true, {}, "", true));
+
+ // The second small form attempt should be throttled, even if throttling
+ // is disabled.
+ EXPECT_FALSE(SendUploadRequest(small_form_structure, true, {}, "", true));
+
+ // All uploads were allowed..
+ histogram_tester.ExpectBucketCount("Autofill.UploadEvent", 1, 4);
+ histogram_tester.ExpectBucketCount(
+ AutofillMetrics::SubmissionSourceToUploadEventMetric(submission_source),
+ 1, 4);
+ histogram_tester.ExpectBucketCount(
+ AutofillMetrics::SubmissionSourceToUploadEventMetric(submission_source),
+ 0, 1);
+
+ // The last middle two uploads were marked as throttle-able.
+ ASSERT_EQ(4u, payloads_.size());
+ for (size_t i = 0; i < payloads_.size(); ++i) {
+ AutofillUploadContents upload_contents;
+ ASSERT_TRUE(upload_contents.ParseFromString(payloads_[i]));
+ EXPECT_EQ(upload_contents.was_throttleable(), (i == 1 || i == 2))
+ << "Wrong was_throttleable value for upload " << i;
+ EXPECT_FALSE(upload_contents.has_randomized_form_metadata());
+ for (const auto& field : upload_contents.field()) {
+ EXPECT_FALSE(field.has_randomized_field_metadata());
+ }
+ }
}
}
TEST_P(AutofillUploadTest, PeriodicReset) {
ASSERT_NE(DISABLED, GetParam());
+ base::test::ScopedFeatureList local_feature;
+ local_feature.InitAndEnableFeatureWithParameters(
+ features::kAutofillUploadThrottling,
+ {{switches::kAutofillUploadThrottlingPeriodInDays, "16"}});
+
FormData form;
FormFieldData field;
@@ -1708,11 +1981,11 @@ TEST_P(AutofillUploadTest, PeriodicReset) {
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
// Advance the clock, but not past the reset period. The pref won't reset,
- // so the upload should never be sent.
- test_clock.Advance(base::TimeDelta::FromDays(27));
+ // so the upload should not be sent.
+ test_clock.Advance(base::TimeDelta::FromDays(15));
EXPECT_FALSE(SendUploadRequest(form_structure, true, {}, "", true));
- // Advance the clock beyond the reset period. The pref should bfde reset and
+ // Advance the clock beyond the reset period. The pref should be reset and
// the upload should succeed.
test_clock.Advance(base::TimeDelta::FromDays(2)); // Total = 29
EXPECT_TRUE(SendUploadRequest(form_structure, true, {}, "", true));
@@ -1779,8 +2052,8 @@ TEST_P(AutofillUploadTest, ResetOnClearUploadHisotry) {
// Note that we omit DEFAULT_URL from the test params. We don't actually want
// the tests to hit the production server. We also excluded DISABLED, since
// these tests exercise "enabled" functionality.
-INSTANTIATE_TEST_CASE_P(All,
- AutofillUploadTest,
- ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
+INSTANTIATE_TEST_SUITE_P(All,
+ AutofillUploadTest,
+ ::testing::Values(FINCHED_URL, COMMAND_LINE_URL));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_driver_factory.h b/chromium/components/autofill/core/browser/autofill_driver_factory.h
index cfb7d05b855..0c1a0a1062d 100644
--- a/chromium/components/autofill/core/browser/autofill_driver_factory.h
+++ b/chromium/components/autofill/core/browser/autofill_driver_factory.h
@@ -34,7 +34,7 @@ class AutofillDriverFactory {
// Handles hiding of the corresponding tab.
void TabHidden();
- AutofillClient* client() { return client_; };
+ AutofillClient* client() { return client_; }
protected:
// The API manipulating the drivers map is protected to guarantee subclasses
diff --git a/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc b/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc
index 0df561935d5..7e11d2a33f8 100644
--- a/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_driver_factory_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill/core/browser/test_autofill_client.h"
diff --git a/chromium/components/autofill/core/browser/autofill_experiments.cc b/chromium/components/autofill/core/browser/autofill_experiments.cc
index 13e96ebe22c..ffc1f9c2c89 100644
--- a/chromium/components/autofill/core/browser/autofill_experiments.cc
+++ b/chromium/components/autofill/core/browser/autofill_experiments.cc
@@ -20,6 +20,7 @@
#include "components/strings/grit/components_strings.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_service_utils.h"
+#include "components/sync/driver/sync_user_settings.h"
#include "components/variations/variations_associated_data.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
@@ -70,7 +71,7 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
// Users who have enabled a passphrase have chosen to not make their sync
// information accessible to Google. Since upload makes credit card data
// available to other Google systems, disable it for passphrase users.
- if (sync_service->IsUsingSecondaryPassphrase())
+ if (sync_service->GetUserSettings()->IsUsingSecondaryPassphrase())
return false;
// Don't offer upload for users that are only syncing locally, since they
diff --git a/chromium/components/autofill/core/browser/autofill_external_delegate.cc b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
index 2f40e6d1911..0024f2d615f 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
@@ -90,7 +90,7 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
Suggestion scan_credit_card(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD));
scan_credit_card.frontend_id = POPUP_ITEM_ID_SCAN_CREDIT_CARD;
- scan_credit_card.icon = base::ASCIIToUTF16("scanCreditCardIcon");
+ scan_credit_card.icon = "scanCreditCardIcon";
suggestions.push_back(scan_credit_card);
}
@@ -108,7 +108,7 @@ void AutofillExternalDelegate::OnSuggestionsReturned(
suggestions.emplace_back(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS));
suggestions.back().frontend_id = POPUP_ITEM_ID_SHOW_ACCOUNT_CARDS;
- suggestions.back().icon = base::ASCIIToUTF16("google");
+ suggestions.back().icon = "google";
}
if (has_autofill_suggestions_)
@@ -358,12 +358,12 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
// So Google Pay Icon is just attached to an existing menu item.
if (is_all_server_suggestions) {
#if defined(OS_ANDROID) || defined(OS_IOS)
- suggestions->back().icon = base::ASCIIToUTF16("googlePay");
+ suggestions->back().icon = "googlePay";
#else
- suggestions->back().icon = base::ASCIIToUTF16(
+ suggestions->back().icon =
ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled()
? "googlePayDark"
- : "googlePay");
+ : "googlePay";
#endif
}
@@ -373,7 +373,7 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
features::kAutofillDownstreamUseGooglePayBrandingOniOS) &&
is_all_server_suggestions) {
Suggestion googlepay_icon;
- googlepay_icon.icon = base::ASCIIToUTF16("googlePay");
+ googlepay_icon.icon = "googlePay";
googlepay_icon.frontend_id = POPUP_ITEM_ID_GOOGLE_PAY_BRANDING;
suggestions->insert(suggestions->begin(), googlepay_icon);
}
@@ -381,10 +381,10 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
#if defined(OS_ANDROID)
if (IsKeyboardAccessoryEnabled()) {
- suggestions->back().icon = base::ASCIIToUTF16("settings");
+ suggestions->back().icon = "settings";
if (IsHintEnabledInKeyboardAccessory() && !query_field_.is_autofilled) {
Suggestion create_icon;
- create_icon.icon = base::ASCIIToUTF16("create");
+ create_icon.icon = "create";
create_icon.frontend_id = POPUP_ITEM_ID_CREATE_HINT;
suggestions->push_back(create_icon);
}
@@ -419,8 +419,12 @@ void AutofillExternalDelegate::InsertDataListValues(
suggestions->insert(suggestions->begin(), data_list_values_.size(),
Suggestion());
for (size_t i = 0; i < data_list_values_.size(); i++) {
+ // A suggestion's label has one line of disambiguating information to show
+ // to the user. However, when the two-line suggestion display experiment is
+ // enabled on desktop, label is replaced by additional label.
(*suggestions)[i].value = data_list_values_[i];
(*suggestions)[i].label = data_list_labels_[i];
+ (*suggestions)[i].additional_label = data_list_labels_[i];
(*suggestions)[i].frontend_id = POPUP_ITEM_ID_DATALIST_ENTRY;
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index 32c3dd956b0..3e7d77e2a14 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -408,15 +408,16 @@ TEST_F(AutofillExternalDelegateUnitTest, UpdateDataListWhileShowingPopup) {
TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutofillDatalistValues) {
IssueOnQuery(kQueryId);
- std::vector<base::string16> data_list_items;
- data_list_items.push_back(base::ASCIIToUTF16("Rick"));
- data_list_items.push_back(base::ASCIIToUTF16("Deckard"));
+ std::vector<base::string16> data_list_values{base::ASCIIToUTF16("Rick"),
+ base::ASCIIToUTF16("Beyonce")};
+ std::vector<base::string16> data_list_labels{base::ASCIIToUTF16("Deckard"),
+ base::ASCIIToUTF16("Knowles")};
EXPECT_CALL(autofill_client_, UpdateAutofillPopupDataListValues(
- data_list_items, data_list_items));
+ data_list_values, data_list_labels));
- external_delegate_->SetCurrentDataListValues(data_list_items,
- data_list_items);
+ external_delegate_->SetCurrentDataListValues(data_list_values,
+ data_list_labels);
// The enums must be cast to ints to prevent compile errors on linux_rel.
auto element_ids = testing::ElementsAre(
@@ -434,6 +435,8 @@ TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutofillDatalistValues) {
std::vector<Suggestion> autofill_item;
autofill_item.push_back(Suggestion());
autofill_item[0].value = ASCIIToUTF16("Rick");
+ autofill_item[0].label = ASCIIToUTF16("Deckard");
+ autofill_item[0].additional_label = ASCIIToUTF16("Deckard");
autofill_item[0].frontend_id = kAutofillProfileId;
external_delegate_->OnSuggestionsReturned(
kQueryId, autofill_item, /*autoselect_first_suggestion=*/false);
@@ -444,15 +447,16 @@ TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutofillDatalistValues) {
TEST_F(AutofillExternalDelegateUnitTest, DuplicateAutocompleteDatalistValues) {
IssueOnQuery(kQueryId);
- std::vector<base::string16> data_list_items;
- data_list_items.push_back(base::ASCIIToUTF16("Rick"));
- data_list_items.push_back(base::ASCIIToUTF16("Deckard"));
+ std::vector<base::string16> data_list_values{base::ASCIIToUTF16("Rick"),
+ base::ASCIIToUTF16("Beyonce")};
+ std::vector<base::string16> data_list_labels{base::ASCIIToUTF16("Deckard"),
+ base::ASCIIToUTF16("Knowles")};
EXPECT_CALL(autofill_client_, UpdateAutofillPopupDataListValues(
- data_list_items, data_list_items));
+ data_list_values, data_list_labels));
- external_delegate_->SetCurrentDataListValues(data_list_items,
- data_list_items);
+ external_delegate_->SetCurrentDataListValues(data_list_values,
+ data_list_labels);
// The enums must be cast to ints to prevent compile errors on linux_rel.
auto element_ids = testing::ElementsAre(
@@ -753,8 +757,7 @@ TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateFillFieldWithValue) {
TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIcon) {
IssueOnQuery(kQueryId);
- auto element_icons = testing::ElementsAre(
- base::string16(), base::ASCIIToUTF16("googlePay"));
+ auto element_icons = testing::ElementsAre(std::string(), "googlePay");
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
@@ -777,8 +780,7 @@ TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIconOniOS) {
IssueOnQuery(kQueryId);
auto element_icons =
- testing::ElementsAre(base::ASCIIToUTF16("googlePay"), base::string16(),
- base::ASCIIToUTF16("googlePay"));
+ testing::ElementsAre("googlePay", std::string(), "googlePay");
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
@@ -801,8 +803,8 @@ TEST_F(AutofillExternalDelegateUnitTest,
IssueOnQuery(kQueryId);
auto element_icons = testing::ElementsAre(
- base::string16(),
- base::string16() /* Autofill setting item does not have icon. */);
+ std::string(),
+ std::string() /* Autofill setting item does not have icon. */);
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
@@ -822,8 +824,8 @@ TEST_F(AutofillExternalDelegateUnitTest,
IssueOnQuery(kQueryId);
auto element_icons = testing::ElementsAre(
- base::string16(),
- base::string16() /* Autofill setting item does not have icon. */);
+ std::string(),
+ std::string() /* Autofill setting item does not have icon. */);
EXPECT_CALL(autofill_client_,
ShowAutofillPopup(_, _, SuggestionVectorIconsAre(element_icons),
false, _));
diff --git a/chromium/components/autofill/core/browser/autofill_field.cc b/chromium/components/autofill/core/browser/autofill_field.cc
index e0eb40ca514..e60544c60ab 100644
--- a/chromium/components/autofill/core/browser/autofill_field.cc
+++ b/chromium/components/autofill/core/browser/autofill_field.cc
@@ -6,8 +6,6 @@
#include <stdint.h>
-#include <utility>
-
#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "components/autofill/core/browser/field_types.h"
@@ -73,18 +71,17 @@ void AutofillField::set_server_type(ServerFieldType type) {
}
void AutofillField::add_possible_types_validities(
- const std::map<ServerFieldType, AutofillProfile::ValidityState>&
- possible_types_validities) {
+ const ServerFieldTypeValidityStateMap& possible_types_validities) {
for (const auto& possible_type_validity : possible_types_validities) {
possible_types_validities_[possible_type_validity.first].push_back(
possible_type_validity.second);
}
}
-std::vector<AutofillProfile::ValidityState>
+std::vector<AutofillDataModel::ValidityState>
AutofillField::get_validities_for_possible_type(ServerFieldType type) {
if (possible_types_validities_.find(type) == possible_types_validities_.end())
- return {AutofillProfile::UNVALIDATED};
+ return {AutofillDataModel::UNVALIDATED};
return possible_types_validities_[type];
}
@@ -172,7 +169,7 @@ FieldSignature AutofillField::GetFieldSignature() const {
}
std::string AutofillField::FieldSignatureAsStr() const {
- return base::UintToString(GetFieldSignature());
+ return base::NumberToString(GetFieldSignature());
}
bool AutofillField::IsFieldFillable() const {
@@ -187,7 +184,7 @@ void AutofillField::NormalizePossibleTypesValidities() {
for (const auto& possible_type : possible_types_) {
if (possible_types_validities_[possible_type].empty()) {
possible_types_validities_[possible_type].push_back(
- AutofillProfile::UNVALIDATED);
+ AutofillDataModel::UNVALIDATED);
}
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_field.h b/chromium/components/autofill/core/browser/autofill_field.h
index 8b565fb0b9d..b7f9069b16f 100644
--- a/chromium/components/autofill/core/browser/autofill_field.h
+++ b/chromium/components/autofill/core/browser/autofill_field.h
@@ -7,7 +7,10 @@
#include <stddef.h>
+#include <map>
#include <string>
+#include <utility>
+#include <vector>
#include "base/macros.h"
#include "base/optional.h"
@@ -22,9 +25,12 @@
namespace autofill {
-typedef std::map<ServerFieldType, std::vector<AutofillProfile::ValidityState>>
+typedef std::map<ServerFieldType, std::vector<AutofillDataModel::ValidityState>>
ServerFieldTypeValidityStatesMap;
+typedef std::map<ServerFieldType, AutofillDataModel::ValidityState>
+ ServerFieldTypeValidityStateMap;
+
class AutofillField : public FormFieldData {
public:
enum PhonePart {
@@ -60,8 +66,7 @@ class AutofillField : public FormFieldData {
void set_heuristic_type(ServerFieldType type);
void set_server_type(ServerFieldType type);
void add_possible_types_validities(
- const std::map<ServerFieldType, AutofillProfile::ValidityState>&
- possible_types_validities);
+ const ServerFieldTypeValidityStateMap& possible_types_validities);
void set_server_predictions(
const std::vector<AutofillQueryResponseContents::Field::FieldPrediction>
predictions) {
@@ -74,8 +79,8 @@ class AutofillField : public FormFieldData {
const ServerFieldTypeValidityStatesMap& possible_types_validities) {
possible_types_validities_ = possible_types_validities;
}
- std::vector<AutofillProfile::ValidityState> get_validities_for_possible_type(
- ServerFieldType);
+ std::vector<AutofillDataModel::ValidityState>
+ get_validities_for_possible_type(ServerFieldType);
void SetHtmlType(HtmlFieldType type, HtmlFieldMode mode);
void set_previously_autofilled(bool previously_autofilled) {
diff --git a/chromium/components/autofill/core/browser/autofill_manager.cc b/chromium/components/autofill/core/browser/autofill_manager.cc
index 95dcd22455c..dcc247b97d0 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager.cc
@@ -51,6 +51,9 @@
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_data_importer.h"
#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/phone_number.h"
@@ -395,10 +398,11 @@ void AutofillManager::OnFormSubmittedImpl(const FormData& form,
form_for_autocomplete, client_->IsAutocompleteEnabled());
if (IsProfileAutofillEnabled()) {
- address_form_event_logger_->OnWillSubmitForm(sync_state_);
+ address_form_event_logger_->OnWillSubmitForm(sync_state_, *submitted_form);
}
if (IsCreditCardAutofillEnabled()) {
- credit_card_form_event_logger_->OnWillSubmitForm(sync_state_);
+ credit_card_form_event_logger_->OnWillSubmitForm(sync_state_,
+ *submitted_form);
}
submitted_form->set_submission_source(source);
@@ -414,19 +418,13 @@ void AutofillManager::OnFormSubmittedImpl(const FormData& form,
submitted_form->set_submission_source(source);
- CreditCard credit_card =
- client_->GetFormDataImporter()->ExtractCreditCardFromForm(
- *submitted_form);
- AutofillMetrics::CardNumberStatus card_number_status =
- GetCardNumberStatus(credit_card);
-
if (IsProfileAutofillEnabled()) {
- address_form_event_logger_->OnFormSubmitted(
- /*force_logging=*/false, card_number_status, sync_state_);
+ address_form_event_logger_->OnFormSubmitted(/*force_logging=*/false,
+ sync_state_, *submitted_form);
}
if (IsCreditCardAutofillEnabled()) {
credit_card_form_event_logger_->OnFormSubmitted(
- enable_ablation_logging_, card_number_status, sync_state_);
+ enable_ablation_logging_, sync_state_, *submitted_form);
}
if (!submitted_form->IsAutofillable())
@@ -711,7 +709,7 @@ void AutofillManager::FillOrPreviewCreditCardForm(
masked_card_, AutofillClient::UNMASK_FOR_AUTOFILL,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr());
credit_card_form_event_logger_->OnDidSelectMaskedServerCardSuggestion(
- form_structure->form_parsed_timestamp(), sync_state_);
+ *form_structure, sync_state_);
return;
}
credit_card_form_event_logger_->OnDidFillSuggestion(
@@ -1228,12 +1226,11 @@ void AutofillManager::Reset() {
form_interactions_ukm_logger_.reset(
new AutofillMetrics::FormInteractionsUkmLogger(
client_->GetUkmRecorder(), client_->GetUkmSourceId()));
- address_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
- /*is_for_credit_card=*/false, driver()->IsInMainFrame(),
- form_interactions_ukm_logger_.get()));
- credit_card_form_event_logger_.reset(new AutofillMetrics::FormEventLogger(
- /*is_for_credit_card=*/true, driver()->IsInMainFrame(),
- form_interactions_ukm_logger_.get()));
+ address_form_event_logger_.reset(new AddressFormEventLogger(
+ driver()->IsInMainFrame(), form_interactions_ukm_logger_.get()));
+ credit_card_form_event_logger_.reset(new CreditCardFormEventLogger(
+ driver()->IsInMainFrame(), form_interactions_ukm_logger_.get(),
+ personal_data_, client_));
#if defined(OS_ANDROID) || defined(OS_IOS)
autofill_assistant_.Reset();
#endif
@@ -1270,16 +1267,15 @@ AutofillManager::AutofillManager(
std::make_unique<AutofillMetrics::FormInteractionsUkmLogger>(
client->GetUkmRecorder(),
client->GetUkmSourceId())),
- address_form_event_logger_(
- std::make_unique<AutofillMetrics::FormEventLogger>(
- /*is_for_credit_card=*/false,
- driver->IsInMainFrame(),
- form_interactions_ukm_logger_.get())),
+ address_form_event_logger_(std::make_unique<AddressFormEventLogger>(
+ driver->IsInMainFrame(),
+ form_interactions_ukm_logger_.get())),
credit_card_form_event_logger_(
- std::make_unique<AutofillMetrics::FormEventLogger>(
- /*is_for_credit_card=*/true,
+ std::make_unique<CreditCardFormEventLogger>(
driver->IsInMainFrame(),
- form_interactions_ukm_logger_.get())),
+ form_interactions_ukm_logger_.get(),
+ personal_data_,
+ client_)),
#if defined(OS_ANDROID) || defined(OS_IOS)
autofill_assistant_(this),
#endif
@@ -1661,10 +1657,10 @@ void AutofillManager::OnFormsParsed(
}
}
if (card_form) {
- credit_card_form_event_logger_->OnDidParseForm();
+ credit_card_form_event_logger_->OnDidParseForm(*form_structure);
}
if (address_form) {
- address_form_event_logger_->OnDidParseForm();
+ address_form_event_logger_->OnDidParseForm(*form_structure);
}
// If a form with the same name was previously filled, and there has not
@@ -1824,8 +1820,7 @@ void AutofillManager::DeterminePossibleFieldTypesForUpload(
base::TrimWhitespace(field->value, base::TRIM_ALL, &value);
for (const AutofillProfile& profile : profiles) {
- std::map<ServerFieldType, AutofillProfile::ValidityState>
- matching_types_validities;
+ ServerFieldTypeValidityStateMap matching_types_validities;
profile.GetMatchingTypesAndValidities(value, app_locale, &matching_types,
&matching_types_validities);
field->add_possible_types_validities(matching_types_validities);
@@ -1838,9 +1833,8 @@ void AutofillManager::DeterminePossibleFieldTypesForUpload(
if (matching_types.empty()) {
matching_types.insert(UNKNOWN_TYPE);
- std::map<ServerFieldType, AutofillProfile::ValidityState>
- matching_types_validities;
- matching_types_validities[UNKNOWN_TYPE] = AutofillProfile::UNVALIDATED;
+ ServerFieldTypeValidityStateMap matching_types_validities;
+ matching_types_validities[UNKNOWN_TYPE] = AutofillDataModel::UNVALIDATED;
field->add_possible_types_validities(matching_types_validities);
}
@@ -2029,7 +2023,8 @@ bool AutofillManager::ShouldTriggerRefill(const FormStructure& form_structure) {
if (itr == filling_contexts_map_.end())
return false;
- address_form_event_logger_->OnDidSeeFillableDynamicForm(sync_state_);
+ address_form_event_logger_->OnDidSeeFillableDynamicForm(sync_state_,
+ form_structure);
FillingContext* filling_context = itr->second.get();
base::TimeTicks now = base::TimeTicks::Now();
@@ -2037,7 +2032,8 @@ bool AutofillManager::ShouldTriggerRefill(const FormStructure& form_structure) {
if (filling_context->attempted_refill &&
delta.InMilliseconds() < kLimitBeforeRefillMs) {
- address_form_event_logger_->OnSubsequentRefillAttempt(sync_state_);
+ address_form_event_logger_->OnSubsequentRefillAttempt(sync_state_,
+ form_structure);
}
return !filling_context->attempted_refill &&
@@ -2051,7 +2047,7 @@ void AutofillManager::TriggerRefill(const FormData& form) {
DCHECK(form_structure);
- address_form_event_logger_->OnDidRefill(sync_state_);
+ address_form_event_logger_->OnDidRefill(sync_state_, *form_structure);
auto itr =
filling_contexts_map_.find(form_structure->GetIdentifierForRefill());
@@ -2117,10 +2113,10 @@ void AutofillManager::GetAvailableSuggestions(
if (context->focused_field->Type().group() == CREDIT_CARD) {
context->is_filling_credit_card = true;
credit_card_form_event_logger_->OnDidInteractWithAutofillableForm(
- context->form_structure->form_signature(), sync_state_);
+ *(context->form_structure), sync_state_);
} else {
address_form_event_logger_->OnDidInteractWithAutofillableForm(
- context->form_structure->form_signature(), sync_state_);
+ *(context->form_structure), sync_state_);
}
}
@@ -2179,19 +2175,4 @@ void AutofillManager::GetAvailableSuggestions(
}
}
-AutofillMetrics::CardNumberStatus AutofillManager::GetCardNumberStatus(
- CreditCard& credit_card) {
- base::string16 number = credit_card.number();
- if (number.empty())
- return AutofillMetrics::EMPTY_CARD;
- else if (!HasCorrectLength(number))
- return AutofillMetrics::WRONG_SIZE_CARD;
- else if (!PassesLuhnCheck(number))
- return AutofillMetrics::FAIL_LUHN_CHECK_CARD;
- else if (personal_data_->IsKnownCard(credit_card))
- return AutofillMetrics::KNOWN_CARD;
- else
- return AutofillMetrics::UNKNOWN_CARD;
-}
-
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_manager.h b/chromium/components/autofill/core/browser/autofill_manager.h
index 588f1ee0693..e9871cd2c89 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.h
+++ b/chromium/components/autofill/core/browser/autofill_manager.h
@@ -29,6 +29,8 @@
#include "components/autofill/core/browser/card_unmask_delegate.h"
#include "components/autofill/core/browser/field_filler.h"
#include "components/autofill/core/browser/form_types.h"
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
#include "components/autofill/core/browser/payments/full_card_request.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/popup_types.h"
@@ -433,9 +435,10 @@ class AutofillManager : public AutofillHandler,
// |FieldTypeGroup|.
bool FormHasAddressField(const FormData& form) WARN_UNUSED_RESULT;
- // Returns a list of values from the stored profiles that match |type| and the
- // value of |field| and returns the labels of the matching profiles. |labels|
- // is filled with the Profile label.
+ // Returns Suggestions corresponding to both the |autofill_field| type and
+ // stored profiles whose values match the contents of |field|. |form| stores
+ // data about the form with which the user is interacting, e.g. the number and
+ // types of form fields.
std::vector<Suggestion> GetProfileSuggestions(
const FormStructure& form,
const FormFieldData& field,
@@ -498,9 +501,6 @@ class AutofillManager : public AutofillHandler,
bool should_notify,
const base::string16& cvc);
- AutofillMetrics::CardNumberStatus GetCardNumberStatus(
- CreditCard& credit_card);
-
// Whether there should be an attemps to refill the form. Returns true if all
// the following are satisfied:
// There have been no refill on that page yet.
@@ -550,9 +550,8 @@ class AutofillManager : public AutofillHandler,
form_interactions_ukm_logger_;
// Utilities for logging form events.
- std::unique_ptr<AutofillMetrics::FormEventLogger> address_form_event_logger_;
- std::unique_ptr<AutofillMetrics::FormEventLogger>
- credit_card_form_event_logger_;
+ std::unique_ptr<AddressFormEventLogger> address_form_event_logger_;
+ std::unique_ptr<CreditCardFormEventLogger> credit_card_form_event_logger_;
// Have we logged whether Autofill is enabled for this page load?
bool has_logged_autofill_enabled_ = false;
diff --git a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
index 68c0d62c8da..20c8ed86951 100644
--- a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -8,6 +8,7 @@
#include <algorithm>
#include <memory>
+#include <tuple>
#include <utility>
#include <vector>
@@ -33,6 +34,7 @@
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
@@ -295,7 +297,6 @@ class AutofillManagerTest : public testing::Test {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
personal_data_.SetPrefService(autofill_client_.GetPrefs());
@@ -1609,9 +1610,9 @@ TEST_F(AutofillManagerTest,
base::HistogramTester histogram_tester;
FormSubmitted(form);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE,
+ 1);
}
// Test that we return normal autofill suggestions when trying to autofill
@@ -4422,8 +4423,8 @@ class ProfileMatchingTypesTest
: public AutofillManagerTest,
public ::testing::WithParamInterface<
std::tuple<ProfileMatchingTypesTestCase,
- int, // AutofillProfile::ValidityState
- bool>> {}; // AutofillProfile::ValidationSource
+ int, // AutofillDataModel::ValidityState
+ bool>> {}; // AutofillDataModel::ValidationSource
const ProfileMatchingTypesTestCase kProfileMatchingTypesTestCases[] = {
// Profile fields matches.
@@ -4517,9 +4518,9 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
// Unpack the test paramters
const auto& test_case = std::get<0>(GetParam());
auto validity_state =
- static_cast<AutofillProfile::ValidityState>(std::get<1>(GetParam()));
+ static_cast<AutofillDataModel::ValidityState>(std::get<1>(GetParam()));
const auto& validation_source =
- static_cast<AutofillProfile::ValidationSource>(std::get<2>(GetParam()));
+ static_cast<AutofillDataModel::ValidationSource>(std::get<2>(GetParam()));
SCOPED_TRACE(base::StringPrintf(
"Test: input_value='%s', field_type=%s, validity_state=%d, "
@@ -4528,8 +4529,8 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
AutofillType(test_case.field_type).ToString().c_str(), validity_state,
validation_source));
- ASSERT_LE(AutofillProfile::UNVALIDATED, validity_state);
- ASSERT_LE(validity_state, AutofillProfile::UNSUPPORTED);
+ ASSERT_LE(AutofillDataModel::UNVALIDATED, validity_state);
+ ASSERT_LE(validity_state, AutofillDataModel::UNSUPPORTED);
// Set up the test profiles.
std::vector<AutofillProfile> profiles;
@@ -4556,11 +4557,11 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
for (auto& profile : profiles) {
if (test_case.field_type == UNKNOWN_TYPE) {
// An UNKNOWN type is always UNVALIDATED
- validity_state = AutofillProfile::UNVALIDATED;
+ validity_state = AutofillDataModel::UNVALIDATED;
} else if (profile.IsAnInvalidPhoneNumber(test_case.field_type)) {
// a phone field is a compound field, an invalid part would make it
// invalid.
- validity_state = AutofillProfile::INVALID;
+ validity_state = AutofillDataModel::INVALID;
}
profile.SetValidityState(test_case.field_type, validity_state,
validation_source);
@@ -4605,19 +4606,19 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
EXPECT_NE(possible_types_validities.end(),
possible_types_validities.find(test_case.field_type));
EXPECT_EQ(possible_types_validities[test_case.field_type][0],
- (validation_source == AutofillProfile::SERVER)
+ (validation_source == AutofillDataModel::SERVER)
? validity_state
- : AutofillProfile::UNVALIDATED);
+ : AutofillDataModel::UNVALIDATED);
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillManagerTest,
ProfileMatchingTypesTest,
testing::Combine(
testing::ValuesIn(kProfileMatchingTypesTestCases),
- testing::Range(static_cast<int>(AutofillProfile::UNVALIDATED),
- static_cast<int>(AutofillProfile::UNSUPPORTED) + 1),
+ testing::Range(static_cast<int>(AutofillDataModel::UNVALIDATED),
+ static_cast<int>(AutofillDataModel::UNSUPPORTED) + 1),
testing::Bool()));
// Tests that DeterminePossibleFieldTypesForUpload is called when a form is
@@ -4683,8 +4684,8 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
"", "Memphis", "Tennessee", "38116", "US",
"(234) 567-8901");
profile.set_guid("00000000-0000-0000-0000-000000000001");
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::VALID,
+ AutofillDataModel::SERVER);
profiles.push_back(profile);
}
{
@@ -4693,8 +4694,8 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
"1331 W Georgia", "", "Vancouver", "Tennessee",
"V4D 4S4", "CA", "(778) 567-8901");
profile.set_guid("00000000-0000-0000-0000-000000000002");
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
profiles.push_back(profile);
}
@@ -4702,7 +4703,7 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
typedef struct {
std::string input_value;
ServerFieldType field_type;
- std::vector<AutofillProfile::ValidityState> expected_validity_states;
+ std::vector<AutofillDataModel::ValidityState> expected_validity_states;
} TestFieldData;
std::vector<TestFieldData> test_cases[3];
@@ -4711,16 +4712,18 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
// possible_field_types would only include the type ADDRESS_HOME_STATE, and
// the corresponding validity of that type would include both VALID and
// INVALID.
- test_cases[0].push_back({"Tennessee",
- ADDRESS_HOME_STATE,
- {AutofillProfile::VALID, AutofillProfile::INVALID}});
+ test_cases[0].push_back(
+ {"Tennessee",
+ ADDRESS_HOME_STATE,
+ {AutofillDataModel::VALID, AutofillDataModel::INVALID}});
// Alice appears only in the second profile as a NAME_FIRST, and it's
// UNVALIDATED.
test_cases[1].push_back(
- {"Alice", NAME_FIRST, {AutofillProfile::UNVALIDATED}});
+ {"Alice", NAME_FIRST, {AutofillDataModel::UNVALIDATED}});
// An UNKNOWN type is always UNVALIDATED.
- test_cases[2].push_back(
- {"What a beautiful day!", UNKNOWN_TYPE, {AutofillProfile::UNVALIDATED}});
+ test_cases[2].push_back({"What a beautiful day!",
+ UNKNOWN_TYPE,
+ {AutofillDataModel::UNVALIDATED}});
for (const std::vector<TestFieldData>& test_fields : test_cases) {
FormData form;
@@ -5392,9 +5395,8 @@ TEST_F(AutofillManagerTest, CreditCardDisabledDoesNotSuggest) {
// Verify that typing "gmail" will match "theking@gmail.com" and
// "buddy@gmail.com" when substring matching is enabled.
TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5414,9 +5416,8 @@ TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens) {
// Verify that typing "apple" will match "123 Apple St." when substring matching
// is enabled.
TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens_CaseIgnored) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5435,9 +5436,8 @@ TEST_F(AutofillManagerTest, DisplaySuggestionsWithMatchingTokens_CaseIgnored) {
// Verify that typing "mail" will not match any of the "@gmail.com" email
// addresses when substring matching is enabled.
TEST_F(AutofillManagerTest, NoSuggestionForNonPrefixTokenMatch) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5454,9 +5454,8 @@ TEST_F(AutofillManagerTest, NoSuggestionForNonPrefixTokenMatch) {
// Verify that typing "pres" will match "Elvis Presley" when substring matching
// is enabled.
TEST_F(AutofillManagerTest, DisplayCreditCardSuggestionsWithMatchingTokens) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5485,9 +5484,8 @@ TEST_F(AutofillManagerTest, DisplayCreditCardSuggestionsWithMatchingTokens) {
// Verify that typing "lvis" will not match any of the credit card name when
// substring matching is enabled.
TEST_F(AutofillManagerTest, NoCreditCardSuggestionsForNonPrefixTokenMatch) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -5695,9 +5693,8 @@ TEST_F(AutofillManagerTest, ShouldShowCreditCardSigninPromo_AddressField) {
// substring matched.
TEST_F(AutofillManagerTest,
DisplaySuggestionsWithPrefixesPrecedeSubstringMatched) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
// Set up our form data.
FormData form;
@@ -6233,12 +6230,10 @@ TEST_F(AutofillManagerTest, DidShowSuggestions_LogAutofillAddressShownMetric) {
histogram_tester.ExpectBucketCount("Autofill.UserHappiness.Address",
AutofillMetrics::SUGGESTIONS_SHOWN_ONCE,
1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// No Autocomplete or credit cards logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6264,12 +6259,10 @@ TEST_F(AutofillManagerTest,
histogram_tester.ExpectBucketCount("Autofill.UserHappiness.CreditCard",
AutofillMetrics::SUGGESTIONS_SHOWN_ONCE,
1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// No Autocomplete or address logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6284,9 +6277,8 @@ TEST_F(AutofillManagerTest,
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, form.fields[0]);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
// No Autocomplete or credit cards logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6303,9 +6295,8 @@ TEST_F(AutofillManagerTest,
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, form.fields[0]);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
// No Autocomplete or address logs.
const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
@@ -6523,6 +6514,6 @@ TEST_P(OnFocusOnFormFieldTest, CreditCardSuggestions_Ablation) {
CheckNoSuggestionsAvailableOnFieldFocus();
}
-INSTANTIATE_TEST_CASE_P(All, OnFocusOnFormFieldTest, testing::Bool());
+INSTANTIATE_TEST_SUITE_P(All, OnFocusOnFormFieldTest, testing::Bool());
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
index caf34836790..bd1bbb316a7 100644
--- a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -304,6 +304,8 @@ TEST_P(AutofillMergeTest, DataDrivenMergeProfiles) {
kIsExpectedToPass);
}
-INSTANTIATE_TEST_CASE_P(, AutofillMergeTest, testing::ValuesIn(GetTestFiles()));
+INSTANTIATE_TEST_SUITE_P(,
+ AutofillMergeTest,
+ testing::ValuesIn(GetTestFiles()));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_metadata.h b/chromium/components/autofill/core/browser/autofill_metadata.h
index 6a70a06bb49..3fbc2e12a26 100644
--- a/chromium/components/autofill/core/browser/autofill_metadata.h
+++ b/chromium/components/autofill/core/browser/autofill_metadata.h
@@ -15,8 +15,8 @@ namespace autofill {
// abstract the data from the metadata.
struct AutofillMetadata {
public:
- AutofillMetadata(){};
- ~AutofillMetadata(){};
+ AutofillMetadata() {}
+ ~AutofillMetadata() {}
bool operator==(const AutofillMetadata&) const;
bool operator!=(const AutofillMetadata&) const;
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.cc b/chromium/components/autofill/core/browser/autofill_metrics.cc
index 6e405659280..b88ad9a0269 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics.cc
@@ -23,12 +23,16 @@
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/submission_source.h"
+#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
namespace autofill {
namespace {
+// Exponential bucket spacing for UKM event data.
+const double kAutofillEventDataBucketSpacing = 2.0;
+
// Note: if adding an enum value here, update the corresponding description for
// AutofillTypeQualityByFieldType in histograms.xml.
enum FieldTypeGroupForMetrics {
@@ -264,21 +268,6 @@ const char* GetQualityMetricTypeSuffix(
}
}
-const char* GetSyncStateSuffix(AutofillSyncSigninState sync_state) {
- switch (sync_state) {
- case AutofillSyncSigninState::kSignedOut:
- return ".SignedOut";
- case AutofillSyncSigninState::kSignedIn:
- return ".SignedIn";
- case AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled:
- return ".SignedInAndWalletSyncTransportEnabled";
- case AutofillSyncSigninState::kSignedInAndSyncFeature:
- return ".SignedInAndSyncFeature";
- case AutofillSyncSigninState::kNumSyncStates:
- return ".Unknown";
- }
-}
-
// Given a set of |possible_types| for a field, select the best type to use as
// the "actual" field type when calculating metrics. If the |predicted_type| is
// among the |possible_types] then use that as the best type (i.e., the
@@ -568,30 +557,6 @@ void LogPredictionQualityMetrics(
is_empty, is_ambiguous);
}
-AutofillMetrics::FormEvent GetCardNumberStatusFormEvent(
- const AutofillMetrics::CardNumberStatus card_number_status) {
- switch (card_number_status) {
- case AutofillMetrics::EMPTY_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD;
- case AutofillMetrics::WRONG_SIZE_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD;
- case AutofillMetrics::FAIL_LUHN_CHECK_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD;
- case AutofillMetrics::KNOWN_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD;
- case AutofillMetrics::UNKNOWN_CARD:
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD;
- }
- NOTREACHED();
- return AutofillMetrics::
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD;
-}
-
} // namespace
const int kMaxBucketsCount = 50;
@@ -614,6 +579,11 @@ void AutofillMetrics::LogSubmittedServerCardExpirationStatusMetric(
}
// static
+void AutofillMetrics::LogMaskedCardComparisonNetworksMatch(bool matches) {
+ UMA_HISTOGRAM_BOOLEAN("Autofill.MaskedCardComparisonNetworksMatch", matches);
+}
+
+// static
void AutofillMetrics::LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(
SaveTypeMetric metric) {
UMA_HISTOGRAM_ENUMERATION(
@@ -622,6 +592,14 @@ void AutofillMetrics::LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(
}
// static
+void AutofillMetrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ SaveTypeMetric metric) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes",
+ metric);
+}
+
+// static
void AutofillMetrics::LogUploadDisallowedForNetworkMetric(
const std::string& network) {
UploadDisallowedForNetworkMetric metric;
@@ -687,19 +665,31 @@ void AutofillMetrics::LogCardUploadDecisionMetrics(
void AutofillMetrics::LogCreditCardInfoBarMetric(
InfoBarMetric metric,
bool is_uploading,
- bool is_requesting_cardholder_name,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision) {
DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
std::string destination = is_uploading ? ".Server" : ".Local";
base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination,
metric, NUM_INFO_BAR_METRICS);
- if (is_requesting_cardholder_name) {
+ if (options.should_request_name_from_user) {
base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination +
".RequestingCardholderName",
metric, NUM_INFO_BAR_METRICS);
}
+ if (options.should_request_expiration_date_from_user) {
+ base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination +
+ ".RequestingExpirationDate",
+ metric, NUM_INFO_BAR_METRICS);
+ }
+
+ if (options.has_non_focusable_field) {
+ base::UmaHistogramEnumeration(
+ "Autofill.CreditCardInfoBar" + destination + ".FromNonFocusableForm",
+ metric, NUM_INFO_BAR_METRICS);
+ }
+
base::UmaHistogramEnumeration(
"Autofill.CreditCardInfoBar" + destination +
PreviousSaveCreditCardPromptUserDecisionToString(
@@ -727,8 +717,7 @@ void AutofillMetrics::LogSaveCardPromptMetric(
SaveCardPromptMetric metric,
bool is_uploading,
bool is_reshow,
- bool is_requesting_cardholder_name,
- bool is_requesting_expiration_date,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision,
security_state::SecurityLevel security_level,
AutofillSyncSigninState sync_state) {
@@ -740,18 +729,23 @@ void AutofillMetrics::LogSaveCardPromptMetric(
base::UmaHistogramEnumeration(metric_with_destination_and_show, metric,
NUM_SAVE_CARD_PROMPT_METRICS);
base::UmaHistogramEnumeration(
- metric_with_destination_and_show + GetSyncStateSuffix(sync_state), metric,
- NUM_SAVE_CARD_PROMPT_METRICS);
- if (is_requesting_cardholder_name) {
+ metric_with_destination_and_show + GetMetricsSyncStateSuffix(sync_state),
+ metric, NUM_SAVE_CARD_PROMPT_METRICS);
+ if (options.should_request_name_from_user) {
base::UmaHistogramEnumeration(
metric_with_destination_and_show + ".RequestingCardholderName", metric,
NUM_SAVE_CARD_PROMPT_METRICS);
}
- if (is_requesting_expiration_date) {
+ if (options.should_request_expiration_date_from_user) {
base::UmaHistogramEnumeration(
metric_with_destination_and_show + ".RequestingExpirationDate", metric,
NUM_SAVE_CARD_PROMPT_METRICS);
}
+ if (options.has_non_focusable_field) {
+ base::UmaHistogramEnumeration(
+ metric_with_destination_and_show + ".FromNonFocusableForm", metric,
+ NUM_SAVE_CARD_PROMPT_METRICS);
+ }
base::UmaHistogramEnumeration(
metric_with_destination_and_show +
PreviousSaveCreditCardPromptUserDecisionToString(
@@ -944,7 +938,19 @@ void AutofillMetrics::LogUnmaskPromptEvent(UnmaskPromptEvent event) {
void AutofillMetrics::LogCardholderNameFixFlowPromptEvent(
CardholderNameFixFlowPromptEvent event) {
UMA_HISTOGRAM_ENUMERATION("Autofill.CardholderNameFixFlowPrompt.Events",
- event, NUM_FIXFLOW_PROMPT_EVENTS);
+ event, NUM_CARDHOLDER_NAME_FIXFLOW_PROMPT_EVENTS);
+}
+
+// static
+void AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ ExpirationDateFixFlowPromptEvent event) {
+ UMA_HISTOGRAM_ENUMERATION("Autofill.ExpirationDateFixFlowPrompt.Events",
+ event);
+}
+
+// static
+void AutofillMetrics::LogExpirationDateFixFlowPromptShown() {
+ UMA_HISTOGRAM_BOOLEAN("Autofill.ExpirationDateFixFlowPromptShown", true);
}
// static
@@ -1246,7 +1252,8 @@ void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(
AutofillSyncSigninState sync_state) {
std::string name("Autofill.IsEnabled.PageLoad");
UMA_HISTOGRAM_BOOLEAN(name, enabled);
- base::UmaHistogramBoolean(name + GetSyncStateSuffix(sync_state), enabled);
+ base::UmaHistogramBoolean(name + GetMetricsSyncStateSuffix(sync_state),
+ enabled);
}
// static
@@ -1670,338 +1677,16 @@ void AutofillMetrics::LogDeveloperEngagementUkm(
.Record(ukm_recorder);
}
-AutofillMetrics::FormEventLogger::FormEventLogger(
- bool is_for_credit_card,
- bool is_in_main_frame,
- AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
- : is_for_credit_card_(is_for_credit_card),
- is_in_main_frame_(is_in_main_frame),
- server_record_type_count_(0),
- local_record_type_count_(0),
- is_context_secure_(false),
- has_logged_interacted_(false),
- has_logged_popup_suppressed_(false),
- has_logged_suggestions_shown_(false),
- has_logged_masked_server_card_suggestion_selected_(false),
- has_logged_suggestion_filled_(false),
- has_logged_will_submit_(false),
- has_logged_submitted_(false),
- has_logged_bank_name_available_(false),
- logged_suggestion_filled_was_server_data_(false),
- logged_suggestion_filled_was_masked_server_card_(false),
- form_interactions_ukm_logger_(form_interactions_ukm_logger) {}
-
-void AutofillMetrics::FormEventLogger::OnDidParseForm() {
- Log(AutofillMetrics::FORM_EVENT_DID_PARSE_FORM);
- if (is_for_credit_card_) {
- base::RecordAction(
- base::UserMetricsAction("Autofill_ParsedCreditCardForm"));
- } else {
- base::RecordAction(base::UserMetricsAction("Autofill_ParsedProfileForm"));
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidInteractWithAutofillableForm(
- FormSignature form_signature,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- if (!has_logged_interacted_) {
- has_logged_interacted_ = true;
- form_interactions_ukm_logger_->LogInteractedWithForm(
- is_for_credit_card_, local_record_type_count_,
- server_record_type_count_, form_signature);
- Log(AutofillMetrics::FORM_EVENT_INTERACTED_ONCE);
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidPollSuggestions(
- const FormFieldData& field,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- // Record only one poll user action for consecutive polls of the same field.
- // This is to avoid recording too many poll actions (for example when a user
- // types in a field, triggering multiple queries) to make the analysis more
- // simple.
- if (!field.SameFieldAs(last_polled_field_)) {
- if (is_for_credit_card_) {
- base::RecordAction(
- base::UserMetricsAction("Autofill_PolledCreditCardSuggestions"));
- } else {
- base::RecordAction(
- base::UserMetricsAction("Autofill_PolledProfileSuggestions"));
- }
-
- last_polled_field_ = field;
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnPopupSuppressed(
- const FormStructure& form,
- const AutofillField& field) {
- Log(AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED);
- if (!has_logged_popup_suppressed_) {
- has_logged_popup_suppressed_ = true;
- Log(AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE);
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidShowSuggestions(
- const FormStructure& form,
- const AutofillField& field,
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- form_interactions_ukm_logger_->LogSuggestionsShown(
- form, field, form_parsed_timestamp);
-
- Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN);
- if (!has_logged_suggestions_shown_) {
- has_logged_suggestions_shown_ = true;
- Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE);
- if (has_logged_bank_name_available_) {
- Log(AutofillMetrics::
- FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE);
- }
- }
-
- if (is_for_credit_card_) {
- base::RecordAction(
- base::UserMetricsAction("Autofill_ShowedCreditCardSuggestions"));
- } else {
- base::RecordAction(
- base::UserMetricsAction("Autofill_ShowedProfileSuggestions"));
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidSelectMaskedServerCardSuggestion(
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- DCHECK(is_for_credit_card_);
- form_interactions_ukm_logger_->LogSelectedMaskedServerCard(
- form_parsed_timestamp);
-
- Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED);
- if (!has_logged_masked_server_card_suggestion_selected_) {
- has_logged_masked_server_card_suggestion_selected_ = true;
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE);
- }
-}
-
-void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
- const CreditCard& credit_card,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- DCHECK(is_for_credit_card_);
- form_interactions_ukm_logger_->LogDidFillSuggestion(
- static_cast<int>(credit_card.record_type()),
- /*is_for_credit_card=*/true, form, field);
-
- if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD)
- Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED);
- else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD)
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
- else
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED);
-
- if (!has_logged_suggestion_filled_) {
- has_logged_suggestion_filled_ = true;
- logged_suggestion_filled_was_server_data_ =
- credit_card.record_type() == CreditCard::MASKED_SERVER_CARD ||
- credit_card.record_type() == CreditCard::FULL_SERVER_CARD;
- logged_suggestion_filled_was_masked_server_card_ =
- credit_card.record_type() == CreditCard::MASKED_SERVER_CARD;
- if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD) {
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE);
- if (has_logged_bank_name_available_) {
- Log(AutofillMetrics::
- FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
- }
- } else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD) {
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE);
- if (has_logged_bank_name_available_) {
- Log(AutofillMetrics::
- FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
- }
- } else {
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
- }
- }
-
- base::RecordAction(
- base::UserMetricsAction("Autofill_FilledCreditCardSuggestion"));
-}
-
-void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
- const AutofillProfile& profile,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- DCHECK(!is_for_credit_card_);
- form_interactions_ukm_logger_->LogDidFillSuggestion(
- static_cast<int>(profile.record_type()),
- /*is_for_for_credit_card=*/false, form, field);
-
- if (profile.record_type() == AutofillProfile::SERVER_PROFILE)
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
- else
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED);
-
- if (!has_logged_suggestion_filled_) {
- has_logged_suggestion_filled_ = true;
- logged_suggestion_filled_was_server_data_ =
- profile.record_type() == AutofillProfile::SERVER_PROFILE;
- Log(profile.record_type() == AutofillProfile::SERVER_PROFILE
- ? AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
- : AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
- }
-
- base::RecordAction(
- base::UserMetricsAction("Autofill_FilledProfileSuggestion"));
-}
-
-void AutofillMetrics::FormEventLogger::OnWillSubmitForm(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- // Not logging this kind of form if we haven't logged a user interaction.
- if (!has_logged_interacted_)
- return;
-
- // Not logging twice.
- if (has_logged_will_submit_)
- return;
- has_logged_will_submit_ = true;
-
- if (!has_logged_suggestion_filled_) {
- Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE);
- } else if (logged_suggestion_filled_was_masked_server_card_) {
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE);
- } else if (logged_suggestion_filled_was_server_data_) {
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE);
- } else {
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE);
- }
-
- if (has_logged_suggestions_shown_) {
- Log(AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE);
- }
-
- base::RecordAction(base::UserMetricsAction("Autofill_OnWillSubmitForm"));
-}
-
-void AutofillMetrics::FormEventLogger::OnFormSubmitted(
- bool force_logging,
- CardNumberStatus card_number_status,
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- // Not logging this kind of form if we haven't logged a user interaction.
- if (!has_logged_interacted_)
- return;
-
- // Not logging twice.
- if (has_logged_submitted_)
- return;
- has_logged_submitted_ = true;
-
- if (!has_logged_suggestion_filled_) {
- Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE);
- } else if (logged_suggestion_filled_was_masked_server_card_) {
- Log(AutofillMetrics::
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE);
- } else if (logged_suggestion_filled_was_server_data_) {
- Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE);
- } else {
- Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE);
- }
-
- if (has_logged_suggestions_shown_ || force_logging) {
- Log(AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE);
- if (is_for_credit_card_ && !has_logged_suggestion_filled_) {
- Log(GetCardNumberStatusFormEvent(card_number_status));
- }
- }
-}
-
-void AutofillMetrics::FormEventLogger::SetBankNameAvailable() {
- has_logged_bank_name_available_ = true;
-}
-
-void AutofillMetrics::FormEventLogger::OnDidSeeFillableDynamicForm(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- Log(AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM);
-}
-
-void AutofillMetrics::FormEventLogger::OnDidRefill(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- Log(AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL);
-}
-
-void AutofillMetrics::FormEventLogger::OnSubsequentRefillAttempt(
- AutofillSyncSigninState sync_state) {
- sync_state_ = sync_state;
- Log(AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL);
-}
-
-void AutofillMetrics::FormEventLogger::Log(FormEvent event) const {
- DCHECK_LT(event, NUM_FORM_EVENTS);
- std::string name("Autofill.FormEvents.");
- if (is_for_credit_card_)
- name += "CreditCard";
- else
- name += "Address";
- base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
-
- // Log again in a different histogram so that iframes can be analyzed on their
- // own.
- base::UmaHistogramEnumeration(
- name + (is_in_main_frame_ ? ".IsInMainFrame" : ".IsInIFrame"), event,
- NUM_FORM_EVENTS);
-
- // Log again in a different histogram for credit card forms on nonsecure
- // pages, so that form interactions on nonsecure pages can be analyzed on
- // their own.
- if (is_for_credit_card_ && !is_context_secure_) {
- base::UmaHistogramEnumeration(name + ".OnNonsecurePage", event,
- NUM_FORM_EVENTS);
- }
-
- // Logging again in a different histogram for segmentation purposes.
- if (server_record_type_count_ == 0 && local_record_type_count_ == 0)
- name += ".WithNoData";
- else if (server_record_type_count_ > 0 && local_record_type_count_ == 0)
- name += ".WithOnlyServerData";
- else if (server_record_type_count_ == 0 && local_record_type_count_ > 0)
- name += ".WithOnlyLocalData";
- else
- name += ".WithBothServerAndLocalData";
- base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
- base::UmaHistogramEnumeration(name + GetSyncStateSuffix(sync_state_), event,
- NUM_FORM_EVENTS);
-}
-
-void AutofillMetrics::FormEventLogger::Log(
- BankNameDisplayedFormEvent event) const {
- DCHECK_LT(event, BANK_NAME_NUM_FORM_EVENTS);
- std::string name("Autofill.FormEvents.CreditCard.BankNameDisplayed");
- base::UmaHistogramEnumeration(name, event, BANK_NAME_NUM_FORM_EVENTS);
-}
-
AutofillMetrics::FormInteractionsUkmLogger::FormInteractionsUkmLogger(
ukm::UkmRecorder* ukm_recorder,
const ukm::SourceId source_id)
- : ukm_recorder_(ukm_recorder), source_id_(source_id) {}
+ : ukm_recorder_(ukm_recorder), source_id_(source_id) {
+ UMA_HISTOGRAM_BOOLEAN("Autofill.CanLogUKM", CanLog());
+}
void AutofillMetrics::FormInteractionsUkmLogger::OnFormsParsed(
const ukm::SourceId source_id) {
- if (ukm_recorder_ == nullptr)
+ if (!CanLog())
return;
source_id_ = source_id;
@@ -2041,17 +1726,6 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogSuggestionsShown(
.Record(ukm_recorder_);
}
-void AutofillMetrics::FormInteractionsUkmLogger::LogSelectedMaskedServerCard(
- const base::TimeTicks& form_parsed_timestamp) {
- if (!CanLog())
- return;
-
- ukm::builders::Autofill_SelectedMaskedServerCard(source_id_)
- .SetMillisecondsSinceFormParsed(
- MillisecondsSinceFormParsed(form_parsed_timestamp))
- .Record(ukm_recorder_);
-}
-
void AutofillMetrics::FormInteractionsUkmLogger::LogDidFillSuggestion(
int record_type,
bool is_for_credit_card,
@@ -2197,6 +1871,23 @@ void AutofillMetrics::LogWalletSyncTransportCardsOptIn(bool is_opted_in) {
"Autofill.HadUserOptedIn_To_WalletSyncTransportServerCards", is_opted_in);
}
+// static
+const char* AutofillMetrics::GetMetricsSyncStateSuffix(
+ AutofillSyncSigninState sync_state) {
+ switch (sync_state) {
+ case AutofillSyncSigninState::kSignedOut:
+ return ".SignedOut";
+ case AutofillSyncSigninState::kSignedIn:
+ return ".SignedIn";
+ case AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled:
+ return ".SignedInAndWalletSyncTransportEnabled";
+ case AutofillSyncSigninState::kSignedInAndSyncFeature:
+ return ".SignedInAndSyncFeature";
+ case AutofillSyncSigninState::kNumSyncStates:
+ return ".Unknown";
+ }
+}
+
void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
bool is_for_credit_card,
bool has_upi_vpa_field,
@@ -2224,6 +1915,24 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
builder.Record(ukm_recorder_);
}
+void AutofillMetrics::FormInteractionsUkmLogger::LogFormEvent(
+ FormEvent form_event,
+ const std::set<FormType>& form_types,
+ const base::TimeTicks& form_parsed_timestamp) {
+ if (!CanLog())
+ return;
+
+ if (form_parsed_timestamp.is_null())
+ return;
+
+ ukm::builders::Autofill_FormEvent builder(source_id_);
+ builder.SetAutofillFormEvent(static_cast<int>(form_event))
+ .SetFormTypes(FormTypesToBitVector(form_types))
+ .SetMillisecondsSinceFormParsed(
+ MillisecondsSinceFormParsed(form_parsed_timestamp))
+ .Record(ukm_recorder_);
+}
+
bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const {
return ukm_recorder_ != nullptr;
}
@@ -2234,7 +1943,10 @@ int64_t AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed(
// Use the pinned timestamp as the current time if it's set.
base::TimeTicks now =
pinned_timestamp_.is_null() ? base::TimeTicks::Now() : pinned_timestamp_;
- return (now - form_parsed_timestamp).InMilliseconds();
+
+ return ukm::GetExponentialBucketMin(
+ (now - form_parsed_timestamp).InMilliseconds(),
+ kAutofillEventDataBucketSpacing);
}
AutofillMetrics::UkmTimestampPin::UkmTimestampPin(
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.h b/chromium/components/autofill/core/browser/autofill_metrics.h
index 2e2f6150140..39c231415ae 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.h
+++ b/chromium/components/autofill/core/browser/autofill_metrics.h
@@ -18,6 +18,7 @@
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_types.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/sync_utils.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/signatures_util.h"
@@ -110,6 +111,11 @@ class AutofillMetrics {
// A pair of dropdowns for the user to select expiration date was surfaced
// in the offer-to-save dialog.
USER_REQUESTED_TO_PROVIDE_EXPIRATION_DATE = 1 << 14,
+ // All the required conditions were satisfied even though the form is
+ // unfocused after the user entered information into it.
+ UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD = 1 << 15,
+ // The card does not satisfy any of the ranges of supported BIN ranges.
+ UPLOAD_NOT_OFFERED_UNSUPPORTED_BIN_RANGE = 1 << 16,
// Update |kNumCardUploadDecisionMetrics| when adding new enum here.
};
@@ -169,7 +175,7 @@ class AutofillMetrics {
// Metric to measure if a submitted card's expiration date matches the same
// server card's expiration date (unmasked or not). Cards are considered to
// be the same if they have the same card number (if unmasked) or if they have
- // the same network and last four digits (if masked).
+ // the same last four digits (if masked).
enum SubmittedServerCardExpirationStatusMetric {
// The submitted card and the unmasked server card had the same expiration
// date.
@@ -592,111 +598,6 @@ class AutofillMetrics {
NUM_USER_HAPPINESS_METRICS,
};
- // Form Events for autofill.
- // These events are triggered separetly for address and credit card forms.
- enum FormEvent {
- // User interacted with a field of this kind of form. Logged only once per
- // page load.
- FORM_EVENT_INTERACTED_ONCE = 0,
- // A dropdown with suggestions was shown.
- FORM_EVENT_SUGGESTIONS_SHOWN,
- // Same as above, but recoreded only once per page load.
- FORM_EVENT_SUGGESTIONS_SHOWN_ONCE,
- // A local suggestion was used to fill the form.
- FORM_EVENT_LOCAL_SUGGESTION_FILLED,
- // A server suggestion was used to fill the form.
- // When dealing with credit cards, this means a full server card was used
- // to fill.
- FORM_EVENT_SERVER_SUGGESTION_FILLED,
- // A masked server card suggestion was used to fill the form.
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED,
- // A suggestion was used to fill the form. The origin type (local or server
- // or masked server card) of the first selected within a page load will
- // determine which of the following two will be fired.
- FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
- FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- // A form was submitted. Depending on the user filling a local, server,
- // masked server card or no suggestion one of the following will be
- // triggered. Only one of the following four will be triggered per page
- // load.
- FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
- FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE,
- FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE,
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
- // A masked server card suggestion was selected to fill the form.
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED,
- // Same as above but only triggered once per page load.
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- // An autofillable form is about to be submitted. If the submission is not
- // interrupted by JavaScript, the "form submitted" events above will also be
- // logged. Depending on the user filling a local, server, masked server card
- // or no suggestion one of the following will be triggered, at most once per
- // page load.
- FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE,
- FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE,
- FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE,
- FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
- // A dropdown with suggestions was shown and a form was submitted after
- // that.
- FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE,
- // A dropdown with suggestions was shown and a form is about to be
- // submitted. If the submission is not interrupted by JavaScript, the "form
- // submitted" event above will also be logged.
- FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE,
- // A dropdown with credit card suggestions was shown, but they were not used
- // to fill the form. Depending on the user submitting a card known by the
- // browser, submitting a card that the browser does not know about,
- // submitting with an empty card number, submitting with a card number of
- // wrong size or submitting with a card number that does not pass luhn
- // check, one of the following will be triggered. At most one of the
- // following five metrics will be triggered per submit.
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
- FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
-
- // The form was changed dynamically. This value has been deprecated.
- FORM_EVENT_DID_SEE_DYNAMIC_FORM,
- // The form was changed dynamically and was fillable.
- FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
- // There was a dynamic change of the form and it got re-filled
- // automatically.
- FORM_EVENT_DID_DYNAMIC_REFILL,
- // The form dynamically changed another time after the refill.
- FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL,
- // The popup was suppressed because the native view couldn't be created.
- FORM_EVENT_POPUP_SUPPRESSED,
- // Same as above, but recoreded only once per page load.
- FORM_EVENT_POPUP_SUPPRESSED_ONCE,
-
- // The form was parsed.
- FORM_EVENT_DID_PARSE_FORM,
-
- NUM_FORM_EVENTS,
- };
-
- // Indicates submitted card information.
- enum CardNumberStatus {
- EMPTY_CARD,
- WRONG_SIZE_CARD,
- FAIL_LUHN_CHECK_CARD,
- KNOWN_CARD,
- UNKNOWN_CARD
- };
-
- // Form Events for autofill with bank name available for display.
- enum BankNameDisplayedFormEvent {
- // A dropdown with suggestions was shown and at least one suggestion has a
- // bank name. Logged at most once per page load.
- FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE = 0,
- // A server suggestion was used to fill the form and at least one suggestion
- // has a bank name. Logged at most once per page load.
- FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
- BANK_NAME_NUM_FORM_EVENTS,
- };
-
// Cardholder name fix flow prompt metrics.
enum CardholderNameFixFlowPromptEvent {
// The prompt was shown.
@@ -707,7 +608,18 @@ class AutofillMetrics {
CARDHOLDER_NAME_FIX_FLOW_PROMPT_DISMISSED,
// The prompt was closed without user interaction.
CARDHOLDER_NAME_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION,
- NUM_FIXFLOW_PROMPT_EVENTS,
+ NUM_CARDHOLDER_NAME_FIXFLOW_PROMPT_EVENTS,
+ };
+
+ // Expiration date fix flow prompt metrics.
+ enum class ExpirationDateFixFlowPromptEvent {
+ // The prompt was accepted by user.
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_ACCEPTED = 0,
+ // The prompt was dismissed by user.
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_DISMISSED,
+ // The prompt was closed without user interaction.
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION,
+ kMaxValue = EXPIRATION_DATE_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION,
};
// Events related to the Unmask Credit Card Prompt.
@@ -872,8 +784,6 @@ class AutofillMetrics {
void LogSuggestionsShown(const FormStructure& form,
const AutofillField& field,
const base::TimeTicks& form_parsed_timestamp);
- void LogSelectedMaskedServerCard(
- const base::TimeTicks& form_parsed_timestamp);
void LogDidFillSuggestion(int record_type,
bool is_for_credit_card,
const FormStructure& form,
@@ -896,6 +806,9 @@ class AutofillMetrics {
AutofillFormSubmittedState state,
const base::TimeTicks& form_parsed_timestamp,
FormSignature form_signature);
+ void LogFormEvent(FormEvent form_event,
+ const std::set<FormType>& form_types,
+ const base::TimeTicks& form_parsed_timestamp);
// Log whether the autofill decided to skip or to fill each
// hidden/representational field.
@@ -941,11 +854,20 @@ class AutofillMetrics {
static void LogSubmittedServerCardExpirationStatusMetric(
SubmittedServerCardExpirationStatusMetric metric);
+ // When a masked card is compared with another card, logs whether the cards'
+ // networks match.
+ static void LogMaskedCardComparisonNetworksMatch(bool matches);
+
// When credit card save is not offered (either at all on mobile or by simply
// not showing the bubble on desktop), logs the occurrence.
static void LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(
SaveTypeMetric metric);
+ // When local card migration is not offered due to max strike limit reached,
+ // logs the occurrence.
+ static void LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ SaveTypeMetric metric);
+
// When credit card upload is disallowed for a particular network, logs which
// network was blocked.
static void LogUploadDisallowedForNetworkMetric(const std::string& network);
@@ -977,7 +899,7 @@ class AutofillMetrics {
static void LogCreditCardInfoBarMetric(
InfoBarMetric metric,
bool is_uploading,
- bool is_requesting_cardholder_name,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision);
static void LogCreditCardFillingInfoBarMetric(InfoBarMetric metric);
static void LogSaveCardRequestExpirationDateReasonMetric(
@@ -986,8 +908,7 @@ class AutofillMetrics {
SaveCardPromptMetric metric,
bool is_uploading,
bool is_reshow,
- bool is_requesting_cardholder_name,
- bool is_requesting_expiration_date_from_user,
+ AutofillClient::SaveCreditCardOptions options,
int previous_save_credit_card_prompt_user_decision,
security_state::SecurityLevel security_level,
AutofillSyncSigninState sync_state);
@@ -1069,6 +990,13 @@ class AutofillMetrics {
static void LogCardholderNameFixFlowPromptEvent(
CardholderNameFixFlowPromptEvent event);
+ // Logs |event| to expiration date fix flow prompt events histogram.
+ static void LogExpirationDateFixFlowPromptEvent(
+ ExpirationDateFixFlowPromptEvent event);
+
+ // Logs the count of expiration date fix flow prompts shown histogram.
+ static void LogExpirationDateFixFlowPromptShown();
+
// Logs the time elapsed between the unmask prompt being shown and it
// being closed.
static void LogUnmaskPromptEventDuration(const base::TimeDelta& duration,
@@ -1303,108 +1231,13 @@ class AutofillMetrics {
// server cards to be shown.
static void LogWalletSyncTransportCardsOptIn(bool is_opted_in);
- // Utility to log autofill form events in the relevant histograms depending on
- // the presence of server and/or local data.
- class FormEventLogger {
- public:
- FormEventLogger(bool is_for_credit_card,
- bool is_in_main_frame,
- FormInteractionsUkmLogger* form_interactions_ukm_logger);
-
- inline void set_server_record_type_count(size_t server_record_type_count) {
- server_record_type_count_ = server_record_type_count;
- }
-
- inline void set_local_record_type_count(size_t local_record_type_count) {
- local_record_type_count_ = local_record_type_count;
- }
-
- inline void set_is_context_secure(bool is_context_secure) {
- is_context_secure_ = is_context_secure;
- }
-
- void OnDidInteractWithAutofillableForm(FormSignature form_signature,
- AutofillSyncSigninState sync_state);
-
- void OnDidPollSuggestions(const FormFieldData& field,
- AutofillSyncSigninState sync_state);
-
- void OnDidParseForm();
-
- void OnDidInteractWithAutofillableForm(FormSignature form_signature);
-
- void OnPopupSuppressed(const FormStructure& form,
- const AutofillField& field);
-
- void OnDidShowSuggestions(const FormStructure& form,
- const AutofillField& field,
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state);
-
- void OnDidSelectMaskedServerCardSuggestion(
- const base::TimeTicks& form_parsed_timestamp,
- AutofillSyncSigninState sync_state);
-
- // In case of masked cards, caller must make sure this gets called before
- // the card is upgraded to a full card.
- void OnDidFillSuggestion(const CreditCard& credit_card,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state);
-
- void OnDidFillSuggestion(const AutofillProfile& profile,
- const FormStructure& form,
- const AutofillField& field,
- AutofillSyncSigninState sync_state);
-
- void OnWillSubmitForm(AutofillSyncSigninState sync_state);
-
- void OnFormSubmitted(bool force_logging,
- const CardNumberStatus card_number_status,
- AutofillSyncSigninState sync_state);
-
- void SetBankNameAvailable();
-
- void OnDidSeeFillableDynamicForm(AutofillSyncSigninState sync_state);
-
- void OnDidRefill(AutofillSyncSigninState sync_state);
-
- void OnSubsequentRefillAttempt(AutofillSyncSigninState sync_state);
-
- private:
- void Log(FormEvent event) const;
- void Log(BankNameDisplayedFormEvent event) const;
-
- bool is_for_credit_card_;
- bool is_in_main_frame_;
- size_t server_record_type_count_;
- size_t local_record_type_count_;
- bool is_context_secure_;
- bool has_logged_interacted_;
- bool has_logged_popup_suppressed_;
- bool has_logged_suggestions_shown_;
- bool has_logged_masked_server_card_suggestion_selected_;
- bool has_logged_suggestion_filled_;
- bool has_logged_will_submit_;
- bool has_logged_submitted_;
- bool has_logged_bank_name_available_;
- bool logged_suggestion_filled_was_server_data_;
- bool logged_suggestion_filled_was_masked_server_card_;
-
- // The last field that was polled for suggestions.
- FormFieldData last_polled_field_;
-
- FormInteractionsUkmLogger*
- form_interactions_ukm_logger_; // Weak reference.
-
- AutofillSyncSigninState sync_state_ =
- AutofillSyncSigninState::kNumSyncStates;
- };
+ static const char* GetMetricsSyncStateSuffix(
+ AutofillSyncSigninState sync_state);
private:
static void Log(AutocompleteEvent event);
- static const int kNumCardUploadDecisionMetrics = 15;
+ static const int kNumCardUploadDecisionMetrics = 17;
DISALLOW_IMPLICIT_CONSTRUCTORS(AutofillMetrics);
};
diff --git a/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc b/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
index 213d7d340fa..87afa30900e 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -23,6 +23,9 @@
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_external_delegate.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
@@ -70,8 +73,6 @@ using UkmCardUploadDecisionType = ukm::builders::Autofill_CardUploadDecision;
using UkmDeveloperEngagementType = ukm::builders::Autofill_DeveloperEngagement;
using UkmInteractedWithFormType = ukm::builders::Autofill_InteractedWithForm;
using UkmSuggestionsShownType = ukm::builders::Autofill_SuggestionsShown;
-using UkmSelectedMaskedServerCardType =
- ukm::builders::Autofill_SelectedMaskedServerCard;
using UkmSuggestionFilledType = ukm::builders::Autofill_SuggestionFilled;
using UkmTextFieldDidChangeType = ukm::builders::Autofill_TextFieldDidChange;
using UkmLogHiddenRepresentationalFieldSkipDecisionType =
@@ -81,10 +82,13 @@ using UkmLogRepeatedServerTypePredictionRationalized =
using UkmFormSubmittedType = ukm::builders::Autofill_FormSubmitted;
using UkmFieldTypeValidationType = ukm::builders::Autofill_FieldTypeValidation;
using UkmFieldFillStatusType = ukm::builders::Autofill_FieldFillStatus;
+using UkmFormEventType = ukm::builders::Autofill_FormEvent;
using ExpectedUkmMetrics =
std::vector<std::vector<std::pair<const char*, int64_t>>>;
+const char* kTestGuid = "00000000-0000-0000-0000-000000000001";
+
int64_t Collapse(uint64_t sig) {
return sig % 1021;
}
@@ -131,10 +135,10 @@ MATCHER(CompareMetricsIgnoringMillisecondsSinceFormParsed, "") {
UkmSuggestionFilledType::kMillisecondsSinceFormParsedName));
}
-void VerifyFormInteractionUkm(const ukm::TestAutoSetUkmRecorder& ukm_recorder,
- const FormData& form,
- const char* event_name,
- const ExpectedUkmMetrics& expected_metrics) {
+void VerifyUkm(const ukm::TestAutoSetUkmRecorder& ukm_recorder,
+ const FormData& form,
+ const char* event_name,
+ const ExpectedUkmMetrics& expected_metrics) {
auto entries = ukm_recorder.GetEntriesByName(event_name);
EXPECT_LE(entries.size(), expected_metrics.size());
@@ -154,16 +158,15 @@ void VerifySubmitFormUkm(const ukm::TestAutoSetUkmRecorder& ukm_recorder,
bool is_for_credit_card,
bool has_upi_vpa_field,
const std::set<FormType>& form_types) {
- VerifyFormInteractionUkm(
- ukm_recorder, form, UkmFormSubmittedType::kEntryName,
- {{{UkmFormSubmittedType::kAutofillFormSubmittedStateName, state},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmFormSubmittedType::kIsForCreditCardName, is_for_credit_card},
- {UkmFormSubmittedType::kHasUpiVpaFieldName, has_upi_vpa_field},
- {UkmFormSubmittedType::kFormTypesName,
- AutofillMetrics::FormTypesToBitVector(form_types)},
- {UkmFormSubmittedType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
+ VerifyUkm(ukm_recorder, form, UkmFormSubmittedType::kEntryName,
+ {{{UkmFormSubmittedType::kAutofillFormSubmittedStateName, state},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmFormSubmittedType::kIsForCreditCardName, is_for_credit_card},
+ {UkmFormSubmittedType::kHasUpiVpaFieldName, has_upi_vpa_field},
+ {UkmFormSubmittedType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector(form_types)},
+ {UkmFormSubmittedType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
}
void AppendFieldFillStatusUkm(const FormData& form,
@@ -218,6 +221,14 @@ void AppendFieldTypeUkm(const FormData& form,
}
}
+void SetProfileTestData(AutofillProfile* profile) {
+ test::SetProfileInfo(profile, "Elvis", "Aaron", "Presley",
+ "theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.",
+ "Apt. 10", "Memphis", "Tennessee", "38116", "US",
+ "12345678901");
+ profile->set_guid(kTestGuid);
+}
+
class MockAutofillClient : public TestAutofillClient {
public:
MockAutofillClient() {}
@@ -242,7 +253,8 @@ class AutofillMetricsTest : public testing::Test {
void CreateAmbiguousProfiles();
// Removes all existing profiles and creates one profile.
- void RecreateProfile();
+ // |is_server| allows creation of |SERVER_PROFILE|.
+ void RecreateProfile(bool is_server);
// Removes all existing credit cards and creates a local, masked server,
// and/or full server credit card, according to the parameters.
@@ -353,16 +365,19 @@ void AutofillMetricsTest::CreateAmbiguousProfiles() {
personal_data_->Refresh();
}
-void AutofillMetricsTest::RecreateProfile() {
+void AutofillMetricsTest::RecreateProfile(bool is_server) {
personal_data_->ClearProfiles();
- AutofillProfile profile;
- test::SetProfileInfo(&profile, "Elvis", "Aaron", "Presley",
- "theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.",
- "Apt. 10", "Memphis", "Tennessee", "38116", "US",
- "12345678901");
- profile.set_guid("00000000-0000-0000-0000-000000000001");
- personal_data_->AddProfile(profile);
+ if (is_server) {
+ AutofillProfile profile(AutofillProfile::SERVER_PROFILE, "server_id");
+ SetProfileTestData(&profile);
+ personal_data_->AddProfile(profile);
+ } else {
+ AutofillProfile profile;
+ SetProfileTestData(&profile);
+ personal_data_->AddProfile(profile);
+ }
+
personal_data_->Refresh();
}
@@ -424,7 +439,7 @@ void AutofillMetricsTest::CreateTestAutofillProfiles() {
"theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.",
"Apt. 10", "Memphis", "Tennessee", "38116", "US",
"12345678901");
- profile1.set_guid("00000000-0000-0000-0000-000000000001");
+ profile1.set_guid(kTestGuid);
personal_data_->AddProfile(profile1);
AutofillProfile profile2;
@@ -453,12 +468,12 @@ class AutofillMetricsIFrameTest : public AutofillMetricsTest,
const std::string credit_card_form_events_frame_histogram_;
};
-INSTANTIATE_TEST_CASE_P(AutofillMetricsTest,
- AutofillMetricsIFrameTest,
- testing::Bool());
+INSTANTIATE_TEST_SUITE_P(AutofillMetricsTest,
+ AutofillMetricsIFrameTest,
+ testing::Bool());
-// Test parameter indicates if the metrics are being logged for a form in an
-// iframe or the main frame. True means the form is in the main frame.
+// Test parameter indicates if the metrics are being logged for a form
+// with a companyname field specified.
class AutofillMetricsCompanyTest : public AutofillMetricsTest,
public testing::WithParamInterface<bool> {
public:
@@ -477,9 +492,9 @@ class AutofillMetricsCompanyTest : public AutofillMetricsTest,
base::test::ScopedFeatureList scoped_feature_list_;
};
-INSTANTIATE_TEST_CASE_P(AutofillMetricsTest,
- AutofillMetricsCompanyTest,
- testing::Bool());
+INSTANTIATE_TEST_SUITE_P(AutofillMetricsTest,
+ AutofillMetricsCompanyTest,
+ testing::Bool());
// Test that we log quality metrics appropriately.
TEST_F(AutofillMetricsTest, QualityMetrics) {
@@ -723,7 +738,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -788,7 +803,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -815,7 +830,7 @@ TEST_F(AutofillMetricsTest,
// correctly.
TEST_F(AutofillMetricsTest, LogHiddenRepresentationalFieldSkipDecision) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
@@ -870,13 +885,13 @@ TEST_F(AutofillMetricsTest, LogHiddenRepresentationalFieldSkipDecision) {
// Simulate filling form.
{
base::UserActionTester user_action_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile.
+ std::string guid(kTestGuid); // local profile.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
}
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form,
UkmLogHiddenRepresentationalFieldSkipDecisionType::kEntryName,
{{{UkmLogHiddenRepresentationalFieldSkipDecisionType::kFormSignatureName,
@@ -1019,7 +1034,7 @@ TEST_F(AutofillMetricsTest, LogRepeatedAddressTypeRationalized) {
.size(),
(size_t)2);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form,
UkmLogRepeatedServerTypePredictionRationalized::kEntryName,
{{{UkmLogRepeatedServerTypePredictionRationalized::kFormSignatureName,
@@ -1134,7 +1149,7 @@ TEST_F(AutofillMetricsTest, LogRepeatedStateCountryTypeRationalized) {
.size(),
(size_t)3);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form,
UkmLogRepeatedServerTypePredictionRationalized::kEntryName,
{{{UkmLogRepeatedServerTypePredictionRationalized::kFormSignatureName,
@@ -1242,7 +1257,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -1323,7 +1338,7 @@ TEST_F(AutofillMetricsTest,
base::UserActionTester user_action_tester;
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Trigger phone number rationalization at filling time.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
@@ -1622,9 +1637,8 @@ TEST_P(QualityMetricsTest, Classification) {
ExpectedUkmMetrics expected_ukm_metrics;
AppendFieldTypeUkm(form, heuristic_types, server_types, actual_types,
&expected_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldTypeValidationType::kEntryName,
- expected_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldTypeValidationType::kEntryName,
+ expected_ukm_metrics);
// Validate the total samples and the crossed (predicted-to-actual) samples.
for (const auto& source : prediction_sources) {
@@ -1722,7 +1736,7 @@ TEST_P(QualityMetricsTest, Classification) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillMetricsTest,
QualityMetricsTest,
testing::Values(QualityMetricsTestCase{NO_SERVER_DATA, EMPTY_TYPE},
@@ -2882,7 +2896,6 @@ TEST_F(AutofillMetricsTest, AutofillIsEnabledAtStartup) {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", true, 1);
}
@@ -2897,7 +2910,6 @@ TEST_F(AutofillMetricsTest, AutofillIsDisabledAtStartup) {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", false, 1);
}
@@ -3107,7 +3119,7 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
"Autofill_FormSubmitted_NonFillable"));
}
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NAME_FULL},
@@ -3128,7 +3140,7 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
// Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
// call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
// |autofill_manager_->FillOrPreviewForm|.
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
{{{UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
@@ -3182,7 +3194,7 @@ TEST_F(AutofillMetricsTest, UpiVpaUkmTest) {
// Test that the profile checkout flow user actions are correctly logged.
TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
@@ -3237,7 +3249,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Simulate selecting a profile suggestions.
{
base::UserActionTester user_action_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile.
+ std::string guid(kTestGuid); // local profile.
external_delegate_->OnQuery(0, form, form.fields.front(), gfx::RectF());
external_delegate_->DidAcceptSuggestion(
ASCIIToUTF16("Test"),
@@ -3249,7 +3261,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Simulate filling a profile suggestion.
{
base::UserActionTester user_action_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile.
+ std::string guid(kTestGuid); // local profile.
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -3270,7 +3282,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
"Autofill_FormSubmitted_NonFillable"));
}
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, ADDRESS_HOME_STATE},
@@ -3291,24 +3303,23 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
// call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
// |autofill_manager_->FillOrPreviewForm|.
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
- {{{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kIsForCreditCardName, false},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.front()))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}},
- {{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, false},
- {UkmSuggestionsShownType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.front()))},
- {UkmSuggestionsShownType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
+ {{{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kIsForCreditCardName, false},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.front()))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}},
+ {{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, false},
+ {UkmSuggestionsShownType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.front()))},
+ {UkmSuggestionsShownType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
// Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState|
// because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|.
VerifySubmitFormUkm(test_ukm_recorder_, form,
@@ -3443,7 +3454,7 @@ TEST_F(AutofillMetricsTest, QueriedCreditCardFormIsSecure) {
// Tests that the Autofill_PolledProfileSuggestions user action is only logged
// once if the field is queried repeatedly.
TEST_F(AutofillMetricsTest, PolledProfileSuggestions_DebounceLogs) {
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up the form data.
FormData form;
@@ -3528,8 +3539,8 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardParsedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
+ "Autofill.FormEvents.CreditCard.WithNoData", FORM_EVENT_DID_PARSE_FORM,
+ 1);
}
// Test that we log interacted form event for credit cards related.
@@ -3562,12 +3573,11 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardInteractedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_INTERACTED_ONCE, 1);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
- histogram_tester.ExpectUniqueSample(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ credit_card_form_events_frame_histogram_, FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
@@ -3581,12 +3591,11 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardInteractedFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->OnQueryFormFieldAutofill(
1, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_INTERACTED_ONCE, 1);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
- histogram_tester.ExpectUniqueSample(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ credit_card_form_events_frame_histogram_, FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
}
@@ -3619,18 +3628,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardPopupSuppressedFormEvents) {
// Simulating popup being suppressed.
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
}
autofill_manager_->Reset();
@@ -3641,18 +3646,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardPopupSuppressedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
}
}
@@ -3685,18 +3686,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
// Simulating new popup being shown.
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -3713,18 +3710,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -3741,18 +3734,14 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(false /* is_new_popup */, form,
field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -3773,21 +3762,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3803,21 +3788,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3835,21 +3816,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3865,21 +3842,17 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -3924,18 +3897,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSelectedFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -3955,18 +3926,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSelectedFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, 1);
}
}
@@ -4006,18 +3975,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(guid, std::string()));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
}
// Reset the autofill manager state.
@@ -4038,18 +4005,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
}
// Recreating cards as the previous test should have upgraded the masked
@@ -4070,18 +4035,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(guid, std::string()));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
@@ -4103,18 +4066,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(guid, std::string()));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
}
// Recreate masked server cards with bank names.
@@ -4140,7 +4101,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4165,7 +4126,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4189,7 +4150,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4213,7 +4174,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
autofill_manager_->MakeFrontendID(guid, std::string()));
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.BankNameDisplayed",
- AutofillMetrics::
+ CreditCardFormEventLogger::
FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
1);
}
@@ -4328,8 +4289,7 @@ TEST_F(AutofillMetricsTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- 1);
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD, 1);
}
TEST_P(AutofillMetricsIFrameTest,
@@ -4370,12 +4330,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
1);
}
@@ -4419,12 +4377,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
1);
}
@@ -4469,12 +4425,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
1);
}
@@ -4519,12 +4473,10 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
1);
}
@@ -4574,38 +4526,32 @@ TEST_P(AutofillMetricsIFrameTest,
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- 0);
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
0);
}
TEST_F(AutofillMetricsTest, ShouldNotLogFormEventNoCardForAddressForm) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -4638,8 +4584,7 @@ TEST_F(AutofillMetricsTest, ShouldNotLogFormEventNoCardForAddressForm) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
- 0);
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD, 0);
}
// Test that we log submitted form events for credit cards.
@@ -4681,16 +4626,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
@@ -4714,18 +4659,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
@@ -4762,18 +4707,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
autofill_manager_->Reset();
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
@@ -4809,18 +4754,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
{{{UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
{UkmSuggestionFilledType::kIsForCreditCardName, true},
@@ -4855,18 +4800,18 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
{{{UkmSuggestionFilledType::kRecordTypeName,
CreditCard::FULL_SERVER_CARD},
@@ -4902,32 +4847,26 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
-
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
- {{{UkmSuggestionFilledType::kRecordTypeName,
- CreditCard::MASKED_SERVER_CARD},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, true},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.back()))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSelectedMaskedServerCardType::kEntryName,
- {{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
+
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
+ {{{UkmSuggestionFilledType::kRecordTypeName,
+ CreditCard::MASKED_SERVER_CARD},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, true},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.back()))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
/*is_for_credit_card=*/true,
@@ -4965,7 +4904,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
autofill_manager_->OnFormSubmitted(form, false,
SubmissionSource::FORM_SUBMISSION);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
{{{UkmFormSubmittedType::kAutofillFormSubmittedStateName,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA},
@@ -4988,70 +4927,66 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
}
@@ -5070,74 +5005,70 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
@@ -5195,16 +5126,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
@@ -5221,16 +5152,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5250,16 +5181,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5280,16 +5211,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5308,18 +5239,16 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
"6011000990139424");
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
- 1);
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, 1);
}
// Recreating cards as the previous test should have upgraded the masked
@@ -5343,70 +5272,66 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics ::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics ::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
}
@@ -5424,70 +5349,66 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
+ histogram_tester.ExpectBucketCount(credit_card_form_events_frame_histogram_,
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.CreditCard",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
credit_card_form_events_frame_histogram_,
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
}
@@ -5529,12 +5450,11 @@ TEST_F(AutofillMetricsTest, MixedParsedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address.WithNoData",
+ FORM_EVENT_DID_PARSE_FORM, 1);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
+ "Autofill.FormEvents.CreditCard.WithNoData", FORM_EVENT_DID_PARSE_FORM,
+ 1);
}
// Test that we log parsed form events for address.
@@ -5564,9 +5484,19 @@ TEST_F(AutofillMetricsTest, AddressParsedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address.WithNoData",
- AutofillMetrics::FORM_EVENT_DID_PARSE_FORM, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address.WithNoData",
+ FORM_EVENT_DID_PARSE_FORM, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(1u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName, FORM_EVENT_DID_PARSE_FORM},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Test that we log interacted form events for address.
@@ -5599,13 +5529,25 @@ TEST_F(AutofillMetricsTest, AddressInteractedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address",
+ FORM_EVENT_INTERACTED_ONCE, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(1u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_INTERACTED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5615,16 +5557,26 @@ TEST_F(AutofillMetricsTest, AddressInteractedFormEvents) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
autofill_manager_->OnQueryFormFieldAutofill(
1, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address",
+ FORM_EVENT_INTERACTED_ONCE, 1);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(1u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_INTERACTED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
}
// Test that popup suppressed form events for address are logged.
TEST_F(AutofillMetricsTest, AddressSuppressedFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5652,16 +5604,32 @@ TEST_F(AutofillMetricsTest, AddressSuppressedFormEvents) {
// Simulating new popup being shown.
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5669,19 +5637,39 @@ TEST_F(AutofillMetricsTest, AddressSuppressedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidSuppressPopup(form, field);
autofill_manager_->DidSuppressPopup(form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE, 1);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(3u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_POPUP_SUPPRESSED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
}
// Test that we log suggestion shown form events for address.
TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5709,21 +5697,36 @@ TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
// Simulating new popup being shown.
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
"Autofill.FormEvents.CreditCard")
["Autofill.FormEvents.CreditCard.BankNameDisplayed"]);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5731,21 +5734,41 @@ TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
"Autofill.FormEvents.CreditCard")
["Autofill.FormEvents.CreditCard.BankNameDisplayed"]);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(3u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_SUGGESTIONS_SHOWN},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5753,24 +5776,26 @@ TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->DidShowSuggestions(false /* is_new_popup */, form,
field);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0);
// Check that the bank name histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(0, histogram_tester.GetTotalCountsForPrefix(
"Autofill.FormEvents.CreditCard")
["Autofill.FormEvents.CreditCard.BankNameDisplayed"]);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(0u, entries.size());
}
}
// Test that we log filled form events for address.
TEST_F(AutofillMetricsTest, AddressFilledFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5797,45 +5822,99 @@ TEST_F(AutofillMetricsTest, AddressFilledFormEvents) {
{
// Simulating selecting/filling a local profile suggestion.
base::HistogramTester histogram_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
+ VerifyUkm(
+ test_ukm_recorder_, form, UkmFormEventType::kEntryName,
+ {{{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}},
+ {{UkmFormEventType::kAutofillFormEventName,
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE},
+ {UkmFormEventType::kFormTypesName,
+ AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0}}});
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
- // Simulating selecting/filling a local profile suggestion.
+ // Simulating selecting/filling a local profile suggestion more than once.
base::HistogramTester histogram_tester;
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ 1);
+ }
+
+ // Create a server profile and reset the autofill manager state.
+ RecreateProfile(/*is_server=*/true);
+ autofill_manager_->Reset();
+ autofill_manager_->AddSeenForm(form, field_types, field_types);
+
+ {
+ // Simulate selecting/filling a server profile suggestion.
+ base::HistogramTester histogram_tester;
+ std::string guid(kTestGuid); // server profile
+ autofill_manager_->FillOrPreviewForm(
+ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
+ autofill_manager_->MakeFrontendID(std::string(), guid));
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
+ }
+
+ autofill_manager_->Reset();
+ autofill_manager_->AddSeenForm(form, field_types, field_types);
+
+ {
+ // Simulate selecting/filling a server profile suggestion more than once.
+ base::HistogramTester histogram_tester;
+ std::string guid(kTestGuid); // server profile
+ autofill_manager_->FillOrPreviewForm(
+ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
+ autofill_manager_->MakeFrontendID(std::string(), guid));
+ autofill_manager_->FillOrPreviewForm(
+ AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
+ autofill_manager_->MakeFrontendID(std::string(), guid));
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED, 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ 1);
}
}
// Test that we log submitted form events for address.
TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -5868,10 +5947,10 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
@@ -5897,10 +5976,10 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
autofill_manager_->Reset();
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
VerifySubmitFormUkm(test_ukm_recorder_, form,
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
@@ -5923,14 +6002,15 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -5938,7 +6018,7 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -5946,10 +6026,10 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
@@ -5968,32 +6048,33 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6006,45 +6087,48 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
+
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
}
}
// Test that we log "will submit" and "submitted" form events for address.
TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
// Create a profile.
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
@@ -6077,14 +6161,15 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6097,14 +6182,15 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6112,7 +6198,7 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
base::HistogramTester histogram_tester;
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
- std::string guid("00000000-0000-0000-0000-000000000001"); // local profile
+ std::string guid(kTestGuid); // local profile
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -6120,14 +6206,15 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6141,42 +6228,45 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 1);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(3u, entries.size());
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
{
@@ -6188,38 +6278,40 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
SubmissionSource::FORM_SUBMISSION);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0);
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
0);
+ // Check if FormEvent UKM is logged properly
+ auto entries =
+ test_ukm_recorder_.GetEntriesByName(UkmFormEventType::kEntryName);
+ EXPECT_EQ(2u, entries.size());
}
}
@@ -6257,12 +6349,13 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.CreditCard.WithNoData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ "Autofill.FormEvents.CreditCard.WithNoData", FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(true /* include_local_credit_card */,
false /* include_masked_server_credit_card */,
@@ -6275,11 +6368,12 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithOnlyLocalData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(false /* include_local_credit_card */,
true /* include_masked_server_credit_card */,
@@ -6292,11 +6386,12 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithOnlyServerData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(false /* include_local_credit_card */,
false /* include_masked_server_credit_card */,
@@ -6309,11 +6404,12 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithOnlyServerData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
+ PurgeUKM();
autofill_manager_->AddSeenForm(form, field_types, field_types);
RecreateCreditCards(true /* include_local_credit_card */,
false /* include_masked_server_credit_card */,
@@ -6326,7 +6422,7 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.CreditCard.WithBothServerAndLocalData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
}
@@ -6362,14 +6458,14 @@ TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) {
autofill_manager_->OnQueryFormFieldAutofill(
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
- "Autofill.FormEvents.Address.WithNoData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ "Autofill.FormEvents.Address.WithNoData", FORM_EVENT_INTERACTED_ONCE,
+ 1);
}
// Reset the autofill manager state.
autofill_manager_->Reset();
autofill_manager_->AddSeenForm(form, field_types, field_types);
- RecreateProfile();
+ RecreateProfile(/*is_server=*/false);
{
// Simulate activating the autofill popup for the street field.
@@ -6378,7 +6474,7 @@ TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) {
0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
histogram_tester.ExpectUniqueSample(
"Autofill.FormEvents.Address.WithOnlyLocalData",
- AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1);
+ FORM_EVENT_INTERACTED_ONCE, 1);
}
}
@@ -6476,14 +6572,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Non fillable form.
@@ -6513,14 +6607,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Fillable form.
@@ -6555,14 +6647,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Autofilled none with suggestions shown.
@@ -6578,18 +6668,17 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
EXPECT_EQ(1, user_action_tester.GetActionCount(
"Autofill_FormSubmitted_FilledNone_SuggestionsShown"));
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
- {{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionsShownType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[2]))},
- {UkmSuggestionsShownType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))},
- {UkmTextFieldDidChangeType::kHeuristicTypeName,
- PHONE_HOME_WHOLE_NUMBER},
- {UkmTextFieldDidChangeType::kHtmlFieldTypeName,
- HTML_TYPE_UNSPECIFIED},
- {UkmTextFieldDidChangeType::kServerTypeName, NO_SERVER_DATA}}});
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
+ {{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionsShownType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[2]))},
+ {UkmSuggestionsShownType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))},
+ {UkmTextFieldDidChangeType::kHeuristicTypeName,
+ PHONE_HOME_WHOLE_NUMBER},
+ {UkmTextFieldDidChangeType::kHtmlFieldTypeName,
+ HTML_TYPE_UNSPECIFIED},
+ {UkmTextFieldDidChangeType::kServerTypeName, NO_SERVER_DATA}}});
expected_form_submission_ukm_metrics.push_back(
{{UkmFormSubmittedType::kAutofillFormSubmittedStateName,
@@ -6602,14 +6691,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Mark one of the fields as autofilled.
@@ -6639,14 +6726,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Mark all of the fillable fields as autofilled.
@@ -6677,14 +6762,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
// Clear out the third field's value.
@@ -6722,14 +6805,12 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
{FormType::ADDRESS_FORM, FormType::UNKNOWN_FORM_TYPE})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
}
@@ -6797,14 +6878,12 @@ TEST_F(
AutofillMetrics::FormTypesToBitVector({FormType::ADDRESS_FORM})},
{UkmFormSubmittedType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}});
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFormSubmittedType::kEntryName,
- expected_form_submission_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
+ expected_form_submission_ukm_metrics);
AppendFieldFillStatusUkm(form, &expected_field_fill_status_ukm_metrics);
- VerifyFormInteractionUkm(test_ukm_recorder_, form,
- UkmFieldFillStatusType::kEntryName,
- expected_field_fill_status_ukm_metrics);
+ VerifyUkm(test_ukm_recorder_, form, UkmFieldFillStatusType::kEntryName,
+ expected_field_fill_status_ukm_metrics);
}
}
@@ -7166,7 +7245,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_AddressForm) {
// Simulate editing an autofilled field.
{
base::HistogramTester histogram_tester;
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
autofill_manager_->FillOrPreviewForm(
AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
autofill_manager_->MakeFrontendID(std::string(), guid));
@@ -7214,12 +7293,11 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_AddressForm) {
autofill_manager_->Reset();
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmInteractedWithFormType::kEntryName,
- {{{UkmInteractedWithFormType::kIsForCreditCardName, false},
- {UkmInteractedWithFormType::kLocalRecordTypeCountName, 0},
- {UkmInteractedWithFormType::kServerRecordTypeCountName, 0}}});
- VerifyFormInteractionUkm(
+ VerifyUkm(test_ukm_recorder_, form, UkmInteractedWithFormType::kEntryName,
+ {{{UkmInteractedWithFormType::kIsForCreditCardName, false},
+ {UkmInteractedWithFormType::kLocalRecordTypeCountName, 0},
+ {UkmInteractedWithFormType::kServerRecordTypeCountName, 0}}});
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
{UkmTextFieldDidChangeType::kHeuristicTypeName,
@@ -7256,24 +7334,23 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_AddressForm) {
Collapse(CalculateFieldSignatureForField(form.fields[1]))},
{UkmSuggestionsShownType::kFormSignatureName,
Collapse(CalculateFormSignature(form))}}});
- VerifyFormInteractionUkm(
- test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
- {{{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, false},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[0]))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}},
- {{UkmSuggestionFilledType::kRecordTypeName,
- AutofillProfile::LOCAL_PROFILE},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[2]))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
- VerifyFormInteractionUkm(
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
+ {{{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, false},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[0]))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}},
+ {{UkmSuggestionFilledType::kRecordTypeName,
+ AutofillProfile::LOCAL_PROFILE},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[2]))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}}});
+ VerifyUkm(
test_ukm_recorder_, form, UkmTextFieldDidChangeType::kEntryName,
{{{UkmTextFieldDidChangeType::kFieldTypeGroupName, NAME},
{UkmTextFieldDidChangeType::kHeuristicTypeName, NAME_FULL},
@@ -8010,13 +8087,12 @@ TEST_F(AutofillMetricsTest, NonsecureCreditCardForm) {
SubmissionSource::FORM_SUBMISSION);
histograms.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.OnNonsecurePage",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
- histograms.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
histograms.ExpectBucketCount(
"Autofill.FormEvents.CreditCard.WithOnlyLocalData",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
}
}
@@ -8066,12 +8142,10 @@ TEST_F(AutofillMetricsTest,
base::HistogramTester histograms;
autofill_manager_->OnFormSubmitted(form, false,
SubmissionSource::FORM_SUBMISSION);
- histograms.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
- histograms.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard",
- AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
+ histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
+ histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
// Check that the nonsecure histogram was not recorded. ExpectBucketCount()
// can't be used here because it expects the histogram to exist.
EXPECT_EQ(
@@ -8180,7 +8254,7 @@ TEST_F(AutofillMetricsTest, MAYBE_AutofillSuggestionShownTest) {
// Simulate and Autofill query on credit card name field.
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
form.fields[0]);
- VerifyFormInteractionUkm(
+ VerifyUkm(
test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
{{{UkmSuggestionsShownType::kMillisecondsSinceFormParsedName, 0},
{UkmSuggestionsShownType::kHeuristicTypeName, CREDIT_CARD_NAME_FULL},
@@ -8217,7 +8291,7 @@ TEST_F(AutofillMetricsTest, DynamicFormMetrics) {
// Simulate seeing.
base::HistogramTester histogram_tester;
autofill_manager_->AddSeenForm(form, field_types, field_types);
- std::string guid("00000000-0000-0000-0000-000000000001");
+ std::string guid(kTestGuid);
// Simulate checking whether to fill a dynamic form before the form was filled
// initially.
@@ -8233,39 +8307,33 @@ TEST_F(AutofillMetricsTest, DynamicFormMetrics) {
// Simulate checking whether to fill a dynamic form after the form was filled
// initially.
autofill_manager_->ShouldTriggerRefill(form_structure);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 0);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_DYNAMIC_REFILL, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
// Trigger a refill, the refill metric should be updated.
autofill_manager_->TriggerRefill(form);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_DYNAMIC_REFILL, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0);
// Trigger a check to see whether a refill should happen. The
autofill_manager_->ShouldTriggerRefill(form_structure);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 2);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 1);
- histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.Address",
- AutofillMetrics::FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ 2);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DID_DYNAMIC_REFILL, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address",
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 1);
}
// Tests that the LogUserHappinessBySecurityLevel are recorded correctly.
@@ -8433,8 +8501,7 @@ TEST_F(AutofillMetricsTest,
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING,
/*is_uploading=*/true, /*is_reshow=*/false,
- /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date=*/false,
+ AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/1,
security_state::SecurityLevel::EV_SECURE, SyncSigninState::kSignedOut);
histogram_tester.ExpectBucketCount(
@@ -8446,8 +8513,7 @@ TEST_F(AutofillMetricsTest,
base::HistogramTester histogram_tester;
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, /*is_uploading=*/false,
- /*is_reshow=*/true, /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date=*/false,
+ /*is_reshow=*/true, AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/0,
security_state::SecurityLevel::SECURE, SyncSigninState::kSignedOut);
histogram_tester.ExpectBucketCount(
@@ -8499,25 +8565,32 @@ TEST_F(AutofillMetricsTest, LogNumberOfAutocompleteEntriesCleanedUp) {
// Verify that we correctly log FormEvent metrics with the appropriate sync
// state.
TEST_F(AutofillMetricsTest, FormEventMetrics_BySyncState) {
+ FormData form;
+ FormStructure form_structure(form);
+ std::vector<FormData> forms(1, form);
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now());
+ autofill_manager_->Reset();
+
{
base::HistogramTester histogram_tester;
- AutofillMetrics::FormEventLogger logger(
- /*is_for_credit_card=*/true, /*is_in_main_frame=*/false,
+ AddressFormEventLogger logger(
+ /*is_in_main_frame=*/true,
/*form_interactions_ukm_logger=*/nullptr);
- logger.OnDidSeeFillableDynamicForm(AutofillSyncSigninState::kSignedOut);
+ logger.OnDidSeeFillableDynamicForm(AutofillSyncSigninState::kSignedOut,
+ form_structure);
histogram_tester.ExpectBucketCount(
- "Autofill.FormEvents.CreditCard.WithNoData.SignedOut",
- AutofillMetrics::FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
+ "Autofill.FormEvents.Address.WithNoData.SignedOut",
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1);
}
{
base::HistogramTester histogram_tester;
- AutofillMetrics::FormEventLogger logger(
- /*is_for_credit_card=*/false, /*is_in_main_frame=*/true,
+ AddressFormEventLogger logger(
+ /*is_in_main_frame=*/true,
/*form_interactions_ukm_logger=*/nullptr);
- logger.OnDidRefill(AutofillSyncSigninState::kSignedIn);
+ logger.OnDidRefill(AutofillSyncSigninState::kSignedIn, form_structure);
histogram_tester.ExpectBucketCount(
"Autofill.FormEvents.Address.WithNoData.SignedIn",
- AutofillMetrics::FORM_EVENT_DID_DYNAMIC_REFILL, 1);
+ FORM_EVENT_DID_DYNAMIC_REFILL, 1);
}
}
@@ -8552,8 +8625,7 @@ TEST_F(AutofillMetricsTest, LogSaveCardPromptMetric_BySyncState) {
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING,
/*is_uploading=*/true, /*is_reshow=*/false,
- /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date_from_user=*/false,
+ AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/1,
security_state::SecurityLevel::EV_SECURE, SyncSigninState::kSignedIn);
histogram_tester.ExpectBucketCount(
@@ -8564,8 +8636,7 @@ TEST_F(AutofillMetricsTest, LogSaveCardPromptMetric_BySyncState) {
base::HistogramTester histogram_tester;
AutofillMetrics::LogSaveCardPromptMetric(
AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, /*is_uploading=*/false,
- /*is_reshow=*/true, /*is_requesting_cardholder_name=*/false,
- /*is_requesting_expiration_date_from_user=*/false,
+ /*is_reshow=*/true, AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/0,
security_state::SecurityLevel::SECURE,
SyncSigninState::kSignedInAndSyncFeature);
diff --git a/chromium/components/autofill/core/browser/autofill_profile.cc b/chromium/components/autofill/core/browser/autofill_profile.cc
index 750b4bb9b34..dd8c59b8f7a 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile.cc
@@ -337,8 +337,7 @@ void AutofillProfile::GetMatchingTypesAndValidities(
const base::string16& text,
const std::string& app_locale,
ServerFieldTypeSet* matching_types,
- std::map<ServerFieldType, AutofillProfile::ValidityState>*
- matching_types_validities) const {
+ ServerFieldTypeValidityStateMap* matching_types_validities) const {
if (!matching_types && !matching_types_validities)
return;
@@ -828,6 +827,38 @@ void AutofillProfile::RecordAndLogUse() {
RecordUse();
}
+bool AutofillProfile::HasGreaterFrescocencyThan(
+ const AutofillProfile* other,
+ base::Time comparison_time,
+ bool use_client_validation,
+ bool use_server_validation) const {
+ bool is_valid = (!use_client_validation || IsValidByClient()) &&
+ (!use_server_validation || IsValidByServer());
+ bool other_is_valid = (!use_client_validation || other->IsValidByClient()) &&
+ (!use_server_validation || other->IsValidByServer());
+ if (is_valid == other_is_valid)
+ return HasGreaterFrecencyThan(other, comparison_time);
+ if (is_valid && !other_is_valid)
+ return true;
+ return false;
+}
+
+bool AutofillProfile::IsValidByClient() const {
+ for (auto const& it : client_validity_states_) {
+ if (it.second == INVALID)
+ return false;
+ }
+ return true;
+}
+
+bool AutofillProfile::IsValidByServer() const {
+ for (auto const& it : server_validity_states_) {
+ if (it.second == INVALID)
+ return false;
+ }
+ return true;
+}
+
bool AutofillProfile::IsAnInvalidPhoneNumber(ServerFieldType type) const {
if (GetValidityState(type, SERVER) == VALID ||
(type != PHONE_HOME_WHOLE_NUMBER && type != PHONE_HOME_NUMBER &&
@@ -860,7 +891,7 @@ bool AutofillProfile::IsAnInvalidPhoneNumber(ServerFieldType type) const {
return false;
}
-AutofillProfile::ValidityState AutofillProfile::GetValidityState(
+AutofillDataModel::ValidityState AutofillProfile::GetValidityState(
ServerFieldType type,
ValidationSource validation_source) const {
if (validation_source == CLIENT) {
@@ -917,7 +948,6 @@ int AutofillProfile::GetClientValidityBitfieldValue() const {
int validity_value = 0;
size_t field_type_shift = 0;
for (ServerFieldType supported_type : kSupportedTypesByClientForValidation) {
- DCHECK(GetValidityState(supported_type, CLIENT) != UNSUPPORTED);
validity_value |= GetValidityState(supported_type, CLIENT)
<< field_type_shift;
field_type_shift += kValidityBitsPerType;
@@ -952,6 +982,29 @@ void AutofillProfile::SetClientValidityFromBitfieldValue(
}
}
+bool AutofillProfile::ShouldSkipFillingOrSuggesting(
+ ServerFieldType type) const {
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileServerValidation) &&
+ GetValidityState(type, AutofillProfile::SERVER) ==
+ AutofillProfile::INVALID) {
+ return true;
+ }
+
+ // We are making an exception and skipping the validation check for address
+ // fields when the country is empty.
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileClientValidation) &&
+ GetValidityState(type, AutofillProfile::CLIENT) ==
+ AutofillProfile::INVALID &&
+ (GroupTypeOfServerFieldType(type) != ADDRESS_HOME ||
+ !GetRawInfo(ADDRESS_HOME_COUNTRY).empty())) {
+ return true;
+ }
+
+ return false;
+}
+
base::string16 AutofillProfile::GetInfoImpl(
const AutofillType& type,
const std::string& app_locale) const {
diff --git a/chromium/components/autofill/core/browser/autofill_profile.h b/chromium/components/autofill/core/browser/autofill_profile.h
index 3d051f90202..bf1c5494762 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.h
+++ b/chromium/components/autofill/core/browser/autofill_profile.h
@@ -9,6 +9,7 @@
#include <iosfwd>
#include <list>
+#include <map>
#include <string>
#include <vector>
@@ -40,26 +41,6 @@ class AutofillProfile : public AutofillDataModel {
SERVER_PROFILE,
};
- enum ValidityState {
- // The field has not been validated.
- UNVALIDATED = 0,
- // The field is empty.
- EMPTY = 1,
- // The field is valid.
- VALID = 2,
- // The field is invalid.
- INVALID = 3,
- // The validation for the field is unsupported.
- UNSUPPORTED = 4,
- };
-
- enum ValidationSource {
- // The validity state is according to the client validation.
- CLIENT = 0,
- // The validity state is according to the server validation.
- SERVER = 1,
- };
-
AutofillProfile(const std::string& guid, const std::string& origin);
// Server profile constructor. The type must be SERVER_PROFILE (this serves
@@ -224,6 +205,24 @@ class AutofillProfile : public AutofillDataModel {
// use and updates |previous_use_date_| to the last value of |use_date_|.
void RecordAndLogUse();
+ // Returns true if the current profile has greater frescocency than the
+ // |other|. Frescocency is a combination of validation score and frecency to
+ // determine the relevance of the profile. Frescocency is a total order: it
+ // puts all the valid profiles before the invalid ones, and uses frecency
+ // (another total order) in case of tie. Please see
+ // AutofillDataModel::HasGreaterFrecencyThan.
+ bool HasGreaterFrescocencyThan(const AutofillProfile* other,
+ base::Time comparison_time,
+ bool use_client_validation,
+ bool use_server_validation) const;
+
+ // Returns false if the profile has any invalid field, according to the client
+ // source of validation.
+ bool IsValidByClient() const;
+ // Returns false if the profile has any invalid field, according to the server
+ // source of validation.
+ bool IsValidByServer() const;
+
const base::Time& previous_use_date() const { return previous_use_date_; }
void set_previous_use_date(const base::Time& time) {
previous_use_date_ = time;
@@ -235,7 +234,7 @@ class AutofillProfile : public AutofillDataModel {
// Returns the validity state of the specified autofill type.
ValidityState GetValidityState(ServerFieldType type,
- ValidationSource source) const;
+ ValidationSource source) const override;
// Sets the validity state of the specified autofill type.
// This should only be called from autofill profile validtion API or in tests.
@@ -275,6 +274,10 @@ class AutofillProfile : public AutofillDataModel {
is_client_validity_states_updated_ = is_client_validity_states_updated;
}
+ // Check for the validity of the data. Leave the field empty if the data is
+ // invalid and the relevant feature is enabled.
+ bool ShouldSkipFillingOrSuggesting(ServerFieldType type) const override;
+
base::WeakPtr<const AutofillProfile> GetWeakPtr() const {
return weak_ptr_factory_.GetWeakPtr();
}
diff --git a/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc b/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc
index f54c16134a2..0d6a67f24a8 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_sync_util.cc
@@ -5,10 +5,14 @@
#include "components/autofill/core/browser/autofill_profile_sync_util.h"
#include "base/guid.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_profile.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "components/autofill/core/browser/autofill_profile_comparator.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/proto/autofill_sync.pb.h"
@@ -54,72 +58,40 @@ std::unique_ptr<EntityData> CreateEntityDataFromAutofillProfile(
entry.is_client_validity_states_updated());
// Set repeated fields.
- if (entry.HasRawInfo(NAME_FIRST)) {
- specifics->add_name_first(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FIRST))));
- }
- if (entry.HasRawInfo(NAME_MIDDLE)) {
- specifics->add_name_middle(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_MIDDLE))));
- }
- if (entry.HasRawInfo(NAME_LAST)) {
- specifics->add_name_last(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_LAST))));
- }
- if (entry.HasRawInfo(NAME_FULL)) {
- specifics->add_name_full(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FULL))));
- }
- if (entry.HasRawInfo(EMAIL_ADDRESS)) {
- specifics->add_email_address(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(EMAIL_ADDRESS))));
- }
- if (entry.HasRawInfo(PHONE_HOME_WHOLE_NUMBER)) {
- specifics->add_phone_home_whole_number(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(PHONE_HOME_WHOLE_NUMBER))));
- }
+ specifics->add_name_first(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FIRST))));
+ specifics->add_name_middle(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_MIDDLE))));
+ specifics->add_name_last(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_LAST))));
+ specifics->add_name_full(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(NAME_FULL))));
+ specifics->add_email_address(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(EMAIL_ADDRESS))));
+ specifics->add_phone_home_whole_number(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(PHONE_HOME_WHOLE_NUMBER))));
// Set simple single-valued fields.
- if (entry.HasRawInfo(COMPANY_NAME)) {
- specifics->set_company_name(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(COMPANY_NAME))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_CITY)) {
- specifics->set_address_home_city(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_CITY))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_STATE)) {
- specifics->set_address_home_state(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STATE))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_ZIP)) {
- specifics->set_address_home_zip(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_ZIP))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_SORTING_CODE)) {
- specifics->set_address_home_sorting_code(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_SORTING_CODE))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY)) {
- specifics->set_address_home_dependent_locality(TruncateUTF8(
- UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_COUNTRY)) {
- specifics->set_address_home_country(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_COUNTRY))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_STREET_ADDRESS)) {
- specifics->set_address_home_street_address(TruncateUTF8(
- UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_LINE1)) {
- specifics->set_address_home_line1(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE1))));
- }
- if (entry.HasRawInfo(ADDRESS_HOME_LINE2)) {
- specifics->set_address_home_line2(
- TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE2))));
- }
+ specifics->set_company_name(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(COMPANY_NAME))));
+ specifics->set_address_home_city(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_CITY))));
+ specifics->set_address_home_state(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STATE))));
+ specifics->set_address_home_zip(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_ZIP))));
+ specifics->set_address_home_sorting_code(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_SORTING_CODE))));
+ specifics->set_address_home_dependent_locality(TruncateUTF8(
+ UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
+ specifics->set_address_home_country(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_COUNTRY))));
+ specifics->set_address_home_street_address(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))));
+ specifics->set_address_home_line1(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE1))));
+ specifics->set_address_home_line2(
+ TruncateUTF8(UTF16ToUTF8(entry.GetRawInfo(ADDRESS_HOME_LINE2))));
return entity_data;
}
@@ -141,78 +113,65 @@ std::unique_ptr<AutofillProfile> CreateAutofillProfileFromSpecifics(
specifics.validity_state_bitfield());
// Set repeated fields.
- if (specifics.name_first_size() > 0) {
- profile->SetRawInfo(NAME_FIRST, UTF8ToUTF16(specifics.name_first(0)));
- }
- if (specifics.name_middle_size() > 0) {
- profile->SetRawInfo(NAME_MIDDLE, UTF8ToUTF16(specifics.name_middle(0)));
- }
- if (specifics.name_last_size() > 0) {
- profile->SetRawInfo(NAME_LAST, UTF8ToUTF16(specifics.name_last(0)));
- }
+ profile->SetRawInfo(NAME_FIRST, UTF8ToUTF16(specifics.name_first_size()
+ ? specifics.name_first(0)
+ : std::string()));
+ profile->SetRawInfo(NAME_MIDDLE, UTF8ToUTF16(specifics.name_middle_size()
+ ? specifics.name_middle(0)
+ : std::string()));
+ profile->SetRawInfo(
+ NAME_LAST, UTF8ToUTF16(specifics.name_last_size() ? specifics.name_last(0)
+ : std::string()));
+ profile->SetRawInfo(
+ EMAIL_ADDRESS,
+ UTF8ToUTF16(specifics.email_address_size() ? specifics.email_address(0)
+ : std::string()));
+ profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
+ UTF8ToUTF16(specifics.phone_home_whole_number_size()
+ ? specifics.phone_home_whole_number(0)
+ : std::string()));
+
+ // Older versions don't have a separate full name; don't overwrite full name
+ // in this case.
if (specifics.name_full_size() > 0) {
profile->SetRawInfo(NAME_FULL, UTF8ToUTF16(specifics.name_full(0)));
}
- if (specifics.email_address_size() > 0) {
- profile->SetRawInfo(EMAIL_ADDRESS, UTF8ToUTF16(specifics.email_address(0)));
- }
- if (specifics.phone_home_whole_number_size() > 0) {
- profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
- UTF8ToUTF16(specifics.phone_home_whole_number(0)));
- }
// Set simple single-valued fields.
- if (specifics.has_company_name()) {
- profile->SetRawInfo(COMPANY_NAME, UTF8ToUTF16(specifics.company_name()));
- }
- if (specifics.has_address_home_city()) {
- profile->SetRawInfo(ADDRESS_HOME_CITY,
- UTF8ToUTF16(specifics.address_home_city()));
- }
- if (specifics.has_address_home_state()) {
- profile->SetRawInfo(ADDRESS_HOME_STATE,
- UTF8ToUTF16(specifics.address_home_state()));
- }
- if (specifics.has_address_home_zip()) {
- profile->SetRawInfo(ADDRESS_HOME_ZIP,
- UTF8ToUTF16(specifics.address_home_zip()));
- }
- if (specifics.has_address_home_sorting_code()) {
- profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE,
- UTF8ToUTF16(specifics.address_home_sorting_code()));
- }
- if (specifics.has_address_home_dependent_locality()) {
- profile->SetRawInfo(
- ADDRESS_HOME_DEPENDENT_LOCALITY,
- UTF8ToUTF16(specifics.address_home_dependent_locality()));
- }
- if (specifics.has_address_home_country()) {
- // Update the country field, which can contain either a country code (if set
- // by a newer version of Chrome), or a country name (if set by an older
- // version of Chrome).
- // TODO(jkrcal): Move this migration logic into Address::SetRawInfo()?
- base::string16 country_name_or_code =
- base::ASCIIToUTF16(specifics.address_home_country());
- std::string country_code =
- CountryNames::GetInstance()->GetCountryCode(country_name_or_code);
- profile->SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16(country_code));
- }
- if (specifics.has_address_home_line1()) {
+ profile->SetRawInfo(COMPANY_NAME, UTF8ToUTF16(specifics.company_name()));
+ profile->SetRawInfo(ADDRESS_HOME_CITY,
+ UTF8ToUTF16(specifics.address_home_city()));
+ profile->SetRawInfo(ADDRESS_HOME_STATE,
+ UTF8ToUTF16(specifics.address_home_state()));
+ profile->SetRawInfo(ADDRESS_HOME_ZIP,
+ UTF8ToUTF16(specifics.address_home_zip()));
+ profile->SetRawInfo(ADDRESS_HOME_SORTING_CODE,
+ UTF8ToUTF16(specifics.address_home_sorting_code()));
+ profile->SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ UTF8ToUTF16(specifics.address_home_dependent_locality()));
+
+ // Update the country field, which can contain either a country code (if set
+ // by a newer version of Chrome), or a country name (if set by an older
+ // version of Chrome).
+ // TODO(jkrcal): Move this migration logic into Address::SetRawInfo()?
+ base::string16 country_name_or_code =
+ base::ASCIIToUTF16(specifics.address_home_country());
+ std::string country_code =
+ CountryNames::GetInstance()->GetCountryCode(country_name_or_code);
+ profile->SetRawInfo(ADDRESS_HOME_COUNTRY, UTF8ToUTF16(country_code));
+
+ // Set either the deprecated subparts (line1 & line2) or the full address
+ // (street_address) if it is present. This is needed because all the address
+ // fields are backed by the same storage.
+ if (specifics.has_address_home_street_address()) {
+ profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+ UTF8ToUTF16(specifics.address_home_street_address()));
+ } else {
profile->SetRawInfo(ADDRESS_HOME_LINE1,
UTF8ToUTF16(specifics.address_home_line1()));
- }
- if (specifics.has_address_home_line2()) {
profile->SetRawInfo(ADDRESS_HOME_LINE2,
UTF8ToUTF16(specifics.address_home_line2()));
}
- // Set first the deprecated subparts (line1 & line2) and only after that the
- // full address (street_address) so that the latter wins in case of conflict.
- // This is needed because all the address fields are backed by the same
- // storage.
- if (specifics.has_address_home_street_address()) {
- profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
- UTF8ToUTF16(specifics.address_home_street_address()));
- }
// This has to be the last one, otherwise setting the raw info may change it.
profile->set_is_client_validity_states_updated(
@@ -235,4 +194,28 @@ std::string GetStorageKeyFromAutofillProfileSpecifics(
return specifics.guid();
}
+bool IsLocalProfileEqualToServerProfile(
+ const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
+ const AutofillProfile& local_profile,
+ const std::string& app_locale) {
+ AutofillProfileComparator comparator(app_locale);
+ for (const auto& server_profile : server_profiles) {
+ // The same logic as when deciding whether to convert into a new profile in
+ // PersonalDataManager::MergeServerAddressesIntoProfiles.
+ if (comparator.AreMergeable(*server_profile, local_profile) &&
+ (!local_profile.IsVerified() || !server_profile->IsVerified())) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin origin) {
+ UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.AddOrUpdateOrigin", origin);
+}
+void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin) {
+ UMA_HISTOGRAM_ENUMERATION("Sync.AutofillProfile.DeleteOrigin", origin);
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_profile_sync_util.h b/chromium/components/autofill/core/browser/autofill_profile_sync_util.h
index a43595262bf..87d677a7155 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_sync_util.h
+++ b/chromium/components/autofill/core/browser/autofill_profile_sync_util.h
@@ -7,6 +7,8 @@
#include <memory>
#include <string>
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include <vector>
namespace syncer {
struct EntityData;
@@ -40,6 +42,24 @@ std::string GetStorageKeyFromAutofillProfile(const AutofillProfile& entry);
std::string GetStorageKeyFromAutofillProfileSpecifics(
const sync_pb::AutofillProfileSpecifics& specifics);
+// TODO(crbug.com/904390): Remove when the investigation is over.
+bool IsLocalProfileEqualToServerProfile(
+ const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
+ const AutofillProfile& local_profile,
+ const std::string& app_locale);
+
+// TODO(crbug.com/904390): Remove when the investigation is over.
+enum class AutofillProfileSyncChangeOrigin {
+ kTrulyLocal = 0,
+ kConvertedLocal = 1,
+ kIncrementalRemote = 2,
+ kInitial = 3,
+ kMaxValue = kInitial,
+};
+void ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin origin);
+void ReportAutofillProfileDeleteOrigin(AutofillProfileSyncChangeOrigin origin);
+
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_PROFILE_SYNC_UTIL_H_
diff --git a/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc
index b9677d58b27..3925a7ee402 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_sync_util_unittest.cc
@@ -133,7 +133,7 @@ TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile) {
entity_data->specifics.autofill_profile().SerializeAsString());
}
-// Test that fields not set for the input are also not set on the output.
+// Test that fields not set for the input are empty in the output.
TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile_Empty) {
AutofillProfile profile(kGuid, std::string());
ASSERT_FALSE(profile.HasRawInfo(NAME_FULL));
@@ -141,8 +141,10 @@ TEST_F(AutofillProfileSyncUtilTest, CreateEntityDataFromAutofillProfile_Empty) {
std::unique_ptr<EntityData> entity_data =
CreateEntityDataFromAutofillProfile(profile);
- EXPECT_EQ(0, entity_data->specifics.autofill_profile().name_full_size());
- EXPECT_FALSE(entity_data->specifics.autofill_profile().has_company_name());
+ EXPECT_EQ(1, entity_data->specifics.autofill_profile().name_full_size());
+ EXPECT_EQ("", entity_data->specifics.autofill_profile().name_full(0));
+ EXPECT_TRUE(entity_data->specifics.autofill_profile().has_company_name());
+ EXPECT_EQ("", entity_data->specifics.autofill_profile().company_name());
}
// Test that long fields get trimmed.
diff --git a/chromium/components/autofill/core/browser/autofill_profile_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
index 2a045233d55..539a255e776 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -15,12 +15,14 @@
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "components/autofill/core/browser/autofill_metadata.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/common/autofill_constants.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/form_field_data.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -306,25 +308,21 @@ TEST(AutofillProfileTest, CreateInferredLabelsI18n_FR) {
"antoine@exemple.com", "Exemple Inc", "8 Rue de Londres",
"", "Paris", "", "75009", "FR", "+33 (0) 1 42 68 53 00");
profiles.back()->set_language_code("fr_FR");
- profiles.back()->SetInfo(
- AutofillType(ADDRESS_HOME_SORTING_CODE), UTF8ToUTF16("CEDEX"), "en-US");
static const char* kExpectedLabels[] = {
"",
"Antoine de Saint-Exupéry",
"Antoine de Saint-Exupéry, 8 Rue de Londres",
"Antoine de Saint-Exupéry, 8 Rue de Londres, Paris",
"Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris",
- "Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris CEDEX",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France, antoine@exemple.com",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
- "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris "
- "CEDEX, France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France, antoine@exemple.com",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
+ "Exemple Inc, Antoine de Saint-Exupéry, 8 Rue de Londres, 75009 Paris, "
+ "France, antoine@exemple.com, +33 (0) 1 42 68 53 00",
};
std::vector<base::string16> labels;
@@ -1058,7 +1056,7 @@ TEST(AutofillProfileTest,
AutofillProfile b = a;
b.SetRawInfo(NAME_FIRST, UTF8ToUTF16("Märion"));
b.SetRawInfo(NAME_MIDDLE, UTF8ToUTF16("Mitchéll"));
- b.SetRawInfo(NAME_LAST,UTF8ToUTF16("Morrison"));
+ b.SetRawInfo(NAME_LAST, UTF8ToUTF16("Morrison"));
b.SetRawInfo(NAME_FULL, UTF8ToUTF16(""));
EXPECT_TRUE(a.SaveAdditionalInfo(b, "en-US"));
@@ -1130,7 +1128,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
{
AutofillProfile profile;
profile.SetValidityState(PHONE_HOME_CITY_AND_NUMBER,
- AutofillProfile::INVALID, AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// It's based on the server side validation.
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(ADDRESS_HOME_LINE1));
@@ -1144,8 +1143,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
{
AutofillProfile profile;
- profile.SetValidityState(PHONE_HOME_CITY_CODE, AutofillProfile::INVALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(PHONE_HOME_CITY_CODE, AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(ADDRESS_HOME_LINE2));
EXPECT_EQ(true, profile.IsAnInvalidPhoneNumber(PHONE_HOME_NUMBER));
@@ -1157,7 +1156,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
{
AutofillProfile profile;
profile.SetValidityState(PHONE_BILLING_COUNTRY_CODE,
- AutofillProfile::INVALID, AutofillProfile::SERVER);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(ADDRESS_HOME_LINE2));
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(PHONE_HOME_NUMBER));
@@ -1167,8 +1167,8 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
}
{
AutofillProfile profile;
- profile.SetValidityState(PHONE_BILLING_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::SERVER);
+ profile.SetValidityState(PHONE_BILLING_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(PHONE_HOME_CITY_CODE));
EXPECT_EQ(false, profile.IsAnInvalidPhoneNumber(PHONE_HOME_NUMBER));
@@ -1179,8 +1179,9 @@ TEST(AutofillProfileTest, IsAnInvalidPhoneNumber) {
}
{
AutofillProfile profile;
- profile.SetValidityState(PHONE_BILLING_WHOLE_NUMBER, AutofillProfile::VALID,
- AutofillProfile::SERVER);
+ profile.SetValidityState(PHONE_BILLING_WHOLE_NUMBER,
+ AutofillDataModel::VALID,
+ AutofillDataModel::SERVER);
EXPECT_EQ(false,
profile.IsAnInvalidPhoneNumber(PHONE_BILLING_COUNTRY_CODE));
@@ -1196,52 +1197,55 @@ TEST(AutofillProfileTest, ValidityStatesClients) {
AutofillProfile profile;
// The default validity state should be UNVALIDATED.
- EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// Make sure setting the validity state works.
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
- EXPECT_EQ(AutofillProfile::VALID,
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, ValidityStatesServer) {
AutofillProfile profile;
+ EXPECT_TRUE(test::GetFullProfile().IsValidByServer());
// The default validity state should be UNVALIDATED.
- EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::SERVER));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::SERVER));
// Make sure setting the validity state works.
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::SERVER);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::SERVER);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::SERVER);
- EXPECT_EQ(AutofillProfile::VALID,
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::SERVER);
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::SERVER));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::SERVER));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::SERVER));
+ AutofillDataModel::SERVER));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::SERVER));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::SERVER));
+ EXPECT_FALSE(profile.IsValidByServer());
}
TEST(AutofillProfileTest, ValidityStates_ClientUnsupportedTypes) {
@@ -1249,26 +1253,26 @@ TEST(AutofillProfileTest, ValidityStates_ClientUnsupportedTypes) {
// The validity state of unsupported types should be UNSUPPORTED.
EXPECT_EQ(
- AutofillProfile::UNSUPPORTED,
- profile.GetValidityState(ADDRESS_HOME_LINE1, AutofillProfile::CLIENT));
+ AutofillDataModel::UNSUPPORTED,
+ profile.GetValidityState(ADDRESS_HOME_LINE1, AutofillDataModel::CLIENT));
// Make sure setting the validity state of an unsupported type does nothing.
- profile.SetValidityState(ADDRESS_HOME_LINE1, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_LINE2, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_LINE1, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_LINE2, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
profile.SetValidityState(PHONE_HOME_CITY_AND_NUMBER,
- AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
- profile.GetValidityState(ADDRESS_HOME_LINE1,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
- profile.GetValidityState(ADDRESS_HOME_LINE2,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ EXPECT_EQ(
+ AutofillDataModel::UNSUPPORTED,
+ profile.GetValidityState(ADDRESS_HOME_LINE1, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::UNSUPPORTED,
+ profile.GetValidityState(ADDRESS_HOME_LINE2, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profile.GetValidityState(PHONE_HOME_CITY_AND_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Country) {
@@ -1278,18 +1282,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Country) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b01
EXPECT_EQ(1, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b10
EXPECT_EQ(2, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b11
EXPECT_EQ(3, profile.GetClientValidityBitfieldValue());
}
@@ -1301,18 +1305,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_State) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b0100
EXPECT_EQ(4, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b1000
EXPECT_EQ(8, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b1100
EXPECT_EQ(12, profile.GetClientValidityBitfieldValue());
}
@@ -1324,18 +1328,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Zip) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b010000
EXPECT_EQ(16, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b100000
EXPECT_EQ(32, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b110000
EXPECT_EQ(48, profile.GetClientValidityBitfieldValue());
}
@@ -1347,18 +1351,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_City) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b01000000
EXPECT_EQ(64, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b10000000
EXPECT_EQ(128, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b11000000
EXPECT_EQ(192, profile.GetClientValidityBitfieldValue());
}
@@ -1371,20 +1375,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_DependentLocality) {
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::EMPTY, AutofillDataModel::CLIENT);
// 0b0100000000
EXPECT_EQ(256, profile.GetClientValidityBitfieldValue());
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::VALID, AutofillDataModel::CLIENT);
// 0b1000000000
EXPECT_EQ(512, profile.GetClientValidityBitfieldValue());
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b1100000000
EXPECT_EQ(768, profile.GetClientValidityBitfieldValue());
}
@@ -1396,18 +1398,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Email) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b010000000000
EXPECT_EQ(1024, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b100000000000
EXPECT_EQ(2048, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b110000000000
EXPECT_EQ(3072, profile.GetClientValidityBitfieldValue());
}
@@ -1419,18 +1421,18 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Phone) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
// 0b01000000000000
EXPECT_EQ(4096, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
// 0b10000000000000
EXPECT_EQ(8192, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
// 0b11000000000000
EXPECT_EQ(12288, profile.GetClientValidityBitfieldValue());
}
@@ -1442,39 +1444,41 @@ TEST(AutofillProfileTest, GetClientValidityBitfieldValue_Mixed) {
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ EXPECT_FALSE(profile.IsValidByClient());
// 0b01110011010010
EXPECT_EQ(7378, profile.GetClientValidityBitfieldValue());
- profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
profile.SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::UNVALIDATED,
- AutofillProfile::AutofillProfile::CLIENT);
- profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID,
- AutofillProfile::AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
+ profile.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ EXPECT_FALSE(profile.IsValidByClient());
// 0b11001110101101
EXPECT_EQ(13229, profile.GetClientValidityBitfieldValue());
}
@@ -1485,24 +1489,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Country) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b01
profile.SetClientValidityFromBitfieldValue(1);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b10
profile.SetClientValidityFromBitfieldValue(2);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b11
profile.SetClientValidityFromBitfieldValue(3);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_State) {
@@ -1511,24 +1519,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_State) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b0100
profile.SetClientValidityFromBitfieldValue(4);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1000
profile.SetClientValidityFromBitfieldValue(8);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1100
profile.SetClientValidityFromBitfieldValue(12);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Zip) {
@@ -1537,24 +1549,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Zip) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b010000
profile.SetClientValidityFromBitfieldValue(16);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b100000
profile.SetClientValidityFromBitfieldValue(32);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b110000
profile.SetClientValidityFromBitfieldValue(48);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_City) {
@@ -1563,24 +1579,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_City) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b01000000
profile.SetClientValidityFromBitfieldValue(64);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b10000000
profile.SetClientValidityFromBitfieldValue(128);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b11000000
profile.SetClientValidityFromBitfieldValue(192);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest,
@@ -1590,24 +1610,28 @@ TEST(AutofillProfileTest,
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b0100000000
profile.SetClientValidityFromBitfieldValue(256);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1000000000
profile.SetClientValidityFromBitfieldValue(512);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b1100000000
profile.SetClientValidityFromBitfieldValue(768);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Email) {
@@ -1616,24 +1640,25 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Email) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b010000000000
profile.SetClientValidityFromBitfieldValue(1024);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b100000000000
profile.SetClientValidityFromBitfieldValue(2048);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b110000000000
profile.SetClientValidityFromBitfieldValue(3072);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Phone) {
@@ -1642,24 +1667,28 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Phone) {
// By default all validity statuses should be set to UNVALIDATED, thus the
// bitfield value should be empty.
EXPECT_EQ(0, profile.GetClientValidityBitfieldValue());
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b01000000000000
profile.SetClientValidityFromBitfieldValue(4096);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b10000000000000
profile.SetClientValidityFromBitfieldValue(8192);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_TRUE(profile.IsValidByClient());
// 0b11000000000000
profile.SetClientValidityFromBitfieldValue(12288);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Mixed) {
@@ -1671,51 +1700,52 @@ TEST(AutofillProfileTest, SetClientValidityFromBitfieldValue_Mixed) {
// 0b01110011010010
profile.SetClientValidityFromBitfieldValue(7378);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+
+ EXPECT_FALSE(profile.IsValidByClient());
// 0b11001110101101
profile.SetClientValidityFromBitfieldValue(13229);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profile.GetValidityState(EMAIL_ADDRESS,
- AutofillProfile::AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_FALSE(profile.IsValidByClient());
}
TEST(AutofillProfileTest, GetMetadata) {
@@ -1835,4 +1865,163 @@ TEST(AutofillProfileTest, EqualsForClientValidationPurpose) {
EXPECT_TRUE(profile.EqualsForClientValidationPurpose(profile3));
}
+// Tests that the skip decision is made correctly.
+TEST(AutofillProfileTest, ShouldSkipFillingOrSuggesting) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{});
+
+ AutofillProfile profile = test::GetFullProfile();
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
+ AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
+ AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_LINE1, AutofillProfile::UNSUPPORTED,
+ AutofillProfile::CLIENT);
+
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_CITY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_STATE));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_COUNTRY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_LINE1));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(EMAIL_ADDRESS));
+
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
+ AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::ASCIIToUTF16(""));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_CITY));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_STATE));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_COUNTRY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_LINE1));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(EMAIL_ADDRESS));
+
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::ASCIIToUTF16("CA"));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_CITY));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_STATE));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_COUNTRY));
+ EXPECT_FALSE(profile.ShouldSkipFillingOrSuggesting(ADDRESS_HOME_LINE1));
+ EXPECT_TRUE(profile.ShouldSkipFillingOrSuggesting(EMAIL_ADDRESS));
+}
+
+enum Expectation { GREATER, LESS, EQUAL };
+
+struct HasGreaterFrescocencyTestCase {
+ const AutofillDataModel::ValidityState client_validity_state_a;
+ const AutofillDataModel::ValidityState server_validity_state_a;
+ const AutofillDataModel::ValidityState client_validity_state_b;
+ const AutofillDataModel::ValidityState server_validity_state_b;
+
+ const bool use_client_validation;
+ const bool use_server_validation;
+ Expectation expectation;
+};
+
+class HasGreaterFrescocencyTest
+ : public testing::TestWithParam<HasGreaterFrescocencyTestCase> {};
+
+TEST_P(HasGreaterFrescocencyTest, HasGreaterFrescocency) {
+ auto test_case = GetParam();
+ AutofillProfile profile_a("00000000-0000-0000-0000-000000000001", "");
+ AutofillProfile profile_b("00000000-0000-0000-0000-000000000002", "");
+
+ profile_a.SetValidityState(EMAIL_ADDRESS, test_case.client_validity_state_a,
+ AutofillDataModel::CLIENT);
+ profile_a.SetValidityState(ADDRESS_HOME_ZIP,
+ test_case.server_validity_state_a,
+ AutofillDataModel::SERVER);
+
+ profile_b.SetValidityState(ADDRESS_HOME_CITY,
+ test_case.client_validity_state_b,
+ AutofillDataModel::CLIENT);
+ profile_b.SetValidityState(PHONE_HOME_NUMBER,
+ test_case.server_validity_state_b,
+ AutofillDataModel::SERVER);
+
+ base::Time now = base::Time::Now();
+
+ if (test_case.expectation == EQUAL) {
+ EXPECT_EQ(profile_a.HasGreaterFrecencyThan(&profile_b, now),
+ profile_a.HasGreaterFrescocencyThan(
+ &profile_b, now, test_case.use_client_validation,
+ test_case.use_server_validation));
+ return;
+ }
+
+ EXPECT_EQ(test_case.expectation == GREATER,
+ profile_a.HasGreaterFrescocencyThan(
+ &profile_b, now, test_case.use_client_validation,
+ test_case.use_server_validation));
+ EXPECT_NE(test_case.expectation == GREATER,
+ profile_b.HasGreaterFrescocencyThan(
+ &profile_a, now, test_case.use_client_validation,
+ test_case.use_server_validation));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ AutofillProfileTest,
+ HasGreaterFrescocencyTest,
+ testing::Values(
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED, false,
+ false, EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, false, false,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, false, true,
+ GREATER},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, false, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::VALID, false, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED, false,
+ true, LESS},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, true, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::UNVALIDATED, AutofillDataModel::VALID, true,
+ true, LESS},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::VALID,
+ AutofillDataModel::VALID, AutofillDataModel::VALID, true, true,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::VALID, AutofillDataModel::INVALID, true, true,
+ GREATER},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::INVALID,
+ AutofillDataModel::INVALID, AutofillDataModel::VALID, true, false,
+ GREATER},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID,
+ AutofillDataModel::UNVALIDATED, AutofillDataModel::VALID, true,
+ false, LESS},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::INVALID,
+ AutofillDataModel::VALID, AutofillDataModel::VALID, true, false,
+ EQUAL},
+ HasGreaterFrescocencyTestCase{
+ AutofillDataModel::VALID, AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::INVALID, AutofillDataModel::INVALID, true, false,
+ GREATER}));
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc b/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc
index 15b2d5926e4..8adf7430917 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validation_util.cc
@@ -41,33 +41,34 @@ using ::i18n::addressinput::MISMATCHING_VALUE;
using ::i18n::addressinput::MISSING_REQUIRED_FIELD;
using ::i18n::addressinput::UNEXPECTED_FIELD;
using ::i18n::addressinput::UNKNOWN_VALUE;
+using ::i18n::addressinput::UNSUPPORTED_FIELD;
using ::i18n::phonenumbers::PhoneNumberUtil;
const AddressField kFields[] = {COUNTRY, ADMIN_AREA, LOCALITY,
DEPENDENT_LOCALITY, POSTAL_CODE};
-const AddressProblem kProblems[] = {UNEXPECTED_FIELD, MISSING_REQUIRED_FIELD,
- UNKNOWN_VALUE, INVALID_FORMAT,
- MISMATCHING_VALUE};
+const AddressProblem kProblems[] = {UNEXPECTED_FIELD, MISSING_REQUIRED_FIELD,
+ UNKNOWN_VALUE, INVALID_FORMAT,
+ MISMATCHING_VALUE, UNSUPPORTED_FIELD};
// If the |address_field| is valid, set the validity state of the
// |address_field| in the |profile| to the |state| and return true.
// Otherwise, return false.
bool SetValidityStateForAddressField(const AutofillProfile* profile,
AddressField address_field,
- AutofillProfile::ValidityState state) {
+ AutofillDataModel::ValidityState state) {
ServerFieldType server_field = i18n::TypeForField(address_field,
/*billing=*/false);
if (server_field == UNKNOWN_TYPE)
return false;
DCHECK(profile);
- profile->SetValidityState(server_field, state, AutofillProfile::CLIENT);
+ profile->SetValidityState(server_field, state, AutofillDataModel::CLIENT);
return true;
}
// Set the validity state of all address fields in the |profile| to |state|.
void SetAllAddressValidityStates(const AutofillProfile* profile,
- AutofillProfile::ValidityState state) {
+ AutofillDataModel::ValidityState state) {
DCHECK(profile);
for (auto field : kFields)
SetValidityStateForAddressField(profile, field, state);
@@ -110,54 +111,56 @@ void InitializeAddressFromProfile(const AutofillProfile& profile,
void SetEmptyValidityIfEmpty(const AutofillProfile* profile) {
if (profile->GetRawInfo(ADDRESS_HOME_COUNTRY).empty())
- profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_STATE).empty())
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_CITY).empty())
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY).empty())
profile->SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::EMPTY, AutofillProfile::CLIENT);
+ AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
if (profile->GetRawInfo(ADDRESS_HOME_ZIP).empty())
- profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
}
void SetInvalidIfUnvalidated(const AutofillProfile* profile) {
if (profile->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
if (profile->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
profile->SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
}
@@ -166,58 +169,62 @@ void MaybeApplyValidToFields(const AutofillProfile* profile) {
// subregion can only be validated if its super-region is VALID. In this
// case, it's VALID if it has not been marked as INVALID or EMPTY.
- if (profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED &&
- profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::VALID) {
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED &&
+ profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::VALID) {
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
if (profile->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED &&
- profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::VALID) {
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED &&
+ profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::VALID) {
profile->SetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::VALID, AutofillProfile::CLIENT);
+ AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
// ZIP only depends on COUNTRY. If it's not so far marked as INVALID or EMPTY,
// then it's VALID.
- if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT) ==
- AutofillProfile::UNVALIDATED) {
- profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::UNVALIDATED) {
+ profile->SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
}
}
void ApplyValidOnlyIfAllChildrenNotInvalid(const AutofillProfile* profile) {
- if (profile->GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID &&
- profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID) {
- profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_STATE,
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID &&
+ profile->GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID) {
+ profile->SetValidityState(ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
- if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID) {
- profile->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ if (profile->GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID) {
+ profile->SetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
if (profile->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID) {
- profile->SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ AutofillDataModel::CLIENT) ==
+ AutofillDataModel::INVALID) {
+ profile->SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
}
@@ -239,7 +246,7 @@ AddressValidator::Status ValidateAddress(const AutofillProfile* profile,
DCHECK(address_validator);
DCHECK(profile);
- SetAllAddressValidityStates(profile, AutofillProfile::UNVALIDATED);
+ SetAllAddressValidityStates(profile, AutofillDataModel::UNVALIDATED);
if (!base::ContainsValue(
CountryDataMap::GetInstance()->country_codes(),
@@ -247,13 +254,14 @@ AddressValidator::Status ValidateAddress(const AutofillProfile* profile,
// If the country code is not in the database, the country code and the
// profile are invalid, and other fields cannot be validated, because it is
// unclear which, if any, rule should apply.
- SetValidityStateForAddressField(profile, COUNTRY, AutofillProfile::INVALID);
+ SetValidityStateForAddressField(profile, COUNTRY,
+ AutofillDataModel::INVALID);
SetEmptyValidityIfEmpty(profile);
return AddressValidator::SUCCESS;
}
// The COUNTRY was already listed in the CountryDataMap, therefore it's valid.
- SetValidityStateForAddressField(profile, COUNTRY, AutofillProfile::VALID);
+ SetValidityStateForAddressField(profile, COUNTRY, AutofillDataModel::VALID);
AddressData address;
InitializeAddressFromProfile(*profile, &address);
@@ -262,9 +270,25 @@ AddressValidator::Status ValidateAddress(const AutofillProfile* profile,
AddressValidator::Status status =
address_validator->ValidateAddress(address, GetFilter(), &problems);
- for (auto problem : problems)
- SetValidityStateForAddressField(profile, problem.first,
- AutofillProfile::INVALID);
+ // The address fields for which validation is not supported by the metadata
+ // will be marked as UNSUPPORTED_FIELDs. These fields should be treated like
+ // VALID fields to stay consistent. INVALID_FORMATs, MISMATCHING_VALUEs or
+ // UNKNOWN_VALUEs are INVALID. MISSING_REQUIRED_FIELD would be marked as EMPTY
+ // along other empty fields. UNEXPECTED_FIELD would mean that there is also no
+ // metadata for validation, therefore, they are also UNSUPPORTED_FIELDs, and
+ // thus they would be treated as VALID fields.
+ for (auto problem : problems) {
+ if (problem.second == UNSUPPORTED_FIELD) {
+ SetValidityStateForAddressField(profile, problem.first,
+ AutofillDataModel::VALID);
+
+ } else if (problem.second == INVALID_FORMAT ||
+ problem.second == MISMATCHING_VALUE ||
+ problem.second == UNKNOWN_VALUE) {
+ SetValidityStateForAddressField(profile, problem.first,
+ AutofillDataModel::INVALID);
+ }
+ }
SetEmptyValidityIfEmpty(profile);
@@ -301,24 +325,24 @@ void ValidateAddressStrictly(const AutofillProfile* profile,
void ValidateEmailAddress(const AutofillProfile* profile) {
const base::string16& email = profile->GetRawInfo(EMAIL_ADDRESS);
if (email.empty()) {
- profile->SetValidityState(EMAIL_ADDRESS, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(EMAIL_ADDRESS, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
return;
}
profile->SetValidityState(EMAIL_ADDRESS,
autofill::IsValidEmailAddress(email)
- ? AutofillProfile::VALID
- : AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ ? AutofillDataModel::VALID
+ : AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
void ValidatePhoneNumber(const AutofillProfile* profile) {
const std::string& phone_number =
base::UTF16ToUTF8(profile->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
if (phone_number.empty()) {
- profile->SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY,
- AutofillProfile::CLIENT);
+ profile->SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY,
+ AutofillDataModel::CLIENT);
return;
}
@@ -329,8 +353,8 @@ void ValidatePhoneNumber(const AutofillProfile* profile) {
// If the country code is not in the database, the phone number cannot be
// validated.
profile->SetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::UNVALIDATED,
- AutofillProfile::CLIENT);
+ AutofillDataModel::UNVALIDATED,
+ AutofillDataModel::CLIENT);
return;
}
@@ -338,9 +362,9 @@ void ValidatePhoneNumber(const AutofillProfile* profile) {
profile->SetValidityState(
PHONE_HOME_WHOLE_NUMBER,
phone_util->IsPossibleNumberForString(phone_number, country_code)
- ? AutofillProfile::VALID
- : AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
+ ? AutofillDataModel::VALID
+ : AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
}
} // namespace profile_validation_util
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc
index 6b609ed9125..59a29b7a650 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validation_util_unittest.cc
@@ -84,24 +84,24 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateFullValidProfileForCanada) {
// Postal Code: "H3B 2T9", Country Code: "CA",
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// For Canada, there is no rule and data to validate the city.
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// Canada doesn't have a dependent locality. It's not filled, and yet the
// profile is valid.
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -112,23 +112,23 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The zip, the state and the city can't be validated, because we don't know
// the country, in the strict validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -138,23 +138,23 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The zip, the state and the city can't be validated, because we don't know
// the country, in the strict validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -165,21 +165,21 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::UNVALIDATED,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaNotExists) {
@@ -188,23 +188,23 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaNotExists) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city can't be validated, because we don't know the state, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyAdminArea) {
@@ -212,23 +212,23 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyAdminArea) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city can't be validated, because we don't know the state, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaFullName) {
@@ -237,21 +237,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaFullName) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaLowerCase) {
@@ -260,21 +260,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_AdminAreaLowerCase) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -284,21 +284,21 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16(admin_area));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -313,21 +313,21 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipNoSpace) {
@@ -336,21 +336,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipNoSpace) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipLowerCase) {
@@ -360,21 +360,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_ValidZipLowerCase) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_InvalidZip) {
@@ -383,21 +383,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_InvalidZip) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(postal_code));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyZip) {
@@ -405,21 +405,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyZip) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyCity) {
@@ -430,21 +430,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateAddress_EmptyCity) {
profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateFullProfile_EmptyFields) {
@@ -455,21 +455,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateFullProfile_EmptyFields) {
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateFullValidProfileForChina) {
@@ -480,21 +480,21 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateFullValidProfileForChina) {
AutofillProfile profile(autofill::test::GetFullValidProfileForChina());
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -504,25 +504,25 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(invalid_city));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The city which is the only dependent field on state is invalid, in the
// strict validation the state would also be considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because we don't know the city,
// in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -535,25 +535,25 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(city));
ValidateAddressTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The city which is the only dependent field on state is invalid, in the
// strict validation the state would also be considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because we don't know the city,
// in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -568,21 +568,21 @@ TEST_F(AutofillProfileValidationUtilTest,
base::UTF8ToUTF16(district));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -593,21 +593,21 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, base::UTF8ToUTF16(""));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -619,23 +619,23 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY, base::UTF8ToUTF16("赫"));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The dependent locality which is the only dependent field on city is
// invalid, in the strict validation the city would also be invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -648,23 +648,23 @@ TEST_F(AutofillProfileValidationUtilTest,
base::UTF8ToUTF16("蒙城县"));
ValidateAddressTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The only that depend on city (dependent locality) is invalid,
// in the strict validation city would also be considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_FullValidProfile) {
@@ -672,18 +672,18 @@ TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_FullValidProfile) {
// Country Code: "CA", Phone Number: "15141112233"
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_EmptyPhoneNumber) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::string16());
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -694,9 +694,9 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -708,103 +708,103 @@ TEST_F(AutofillProfileValidationUtilTest,
profile.SetRawInfo(ADDRESS_HOME_COUNTRY, base::UTF8ToUTF16(country_code));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::string16());
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_InvalidPhoneNumber) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("151411122334"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("1(514)111-22-334"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("251411122334"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("Hello!"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidatePhone_ValidPhoneNumber) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("5141112233"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("514-111-2233"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("1(514)111-22-33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("+1 514 111 22 33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("+1 (514)-111-22-33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("(514)-111-22-33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("+1 650 GOO OGLE"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER,
base::ASCIIToUTF16("778 111 22 33"));
ValidatePhoneTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_FullValidProfile) {
@@ -812,16 +812,16 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_FullValidProfile) {
// Email: "alice@wonderland.ca"
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_EmptyEmailAddress) {
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(EMAIL_ADDRESS, base::string16());
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::EMPTY,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -829,24 +829,24 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("Hello!"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("alice.wonderland"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("alice@"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS,
base::ASCIIToUTF16("alice@=wonderland.com"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_ValidEmailAddress) {
@@ -854,40 +854,40 @@ TEST_F(AutofillProfileValidationUtilTest, ValidateEmail_ValidEmailAddress) {
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("alice@wonderland"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS,
base::ASCIIToUTF16("alice@wonderland.fiction"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
profile.SetRawInfo(EMAIL_ADDRESS,
base::ASCIIToUTF16("alice+cat@wonderland.fiction.book"));
ValidateEmailTest(&profile);
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest, ValidateProfile_FullValidProfile) {
// This is a full valid profile:
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
ValidateProfileTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -896,20 +896,26 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("ABC 123"));
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -918,20 +924,26 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::ASCIIToUTF16("33"));
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -940,20 +952,26 @@ TEST_F(AutofillProfileValidationUtilTest,
AutofillProfile profile(autofill::test::GetFullValidProfileForCanada());
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("fakeaddress"));
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profile.GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(EMAIL_ADDRESS, AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -968,33 +986,33 @@ TEST_F(AutofillProfileValidationUtilTest,
ValidateProfileTest(&profile);
// The fields that depend on country (state and zip) are both invalid,
// therefore in the strict validation this is considered as invalid.
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The state is not a Chinese state, so it's considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city can't be validated, because the state value is not
// valid, in the strict validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
// The zip is not a Chinese one, therefore it's invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -1010,35 +1028,35 @@ TEST_F(AutofillProfileValidationUtilTest,
// The fields that depend on Country (state and zip) are both invalid,
// therefore in the strict validation this is considered as invalid.
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The state is not a Canadian state, so it's considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// We can't validate city, because state is not valid, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality is not a Canadian field, so it's considered as
// invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
// The zip is not a Canadian one, therefore it's invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -1052,34 +1070,34 @@ TEST_F(AutofillProfileValidationUtilTest,
ValidateProfileTest(&profile);
- EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
// The only field that depends on state (city) is invalid, in the strict
// validation this makes state also invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// The city is in another province.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because the city value is not
// valid, in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
TEST_F(AutofillProfileValidationUtilTest,
@@ -1093,33 +1111,33 @@ TEST_F(AutofillProfileValidationUtilTest,
ValidateProfileTest(&profile);
+ EXPECT_EQ(AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_COUNTRY,
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_COUNTRY, AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::EMPTY,
- profile.GetValidityState(ADDRESS_HOME_STATE, AutofillProfile::CLIENT));
+ AutofillDataModel::EMPTY,
+ profile.GetValidityState(ADDRESS_HOME_STATE, AutofillDataModel::CLIENT));
// City can't be validated, because the state is missing, in the strict
// validation this is considered as invalid.
EXPECT_EQ(
- AutofillProfile::INVALID,
- profile.GetValidityState(ADDRESS_HOME_CITY, AutofillProfile::CLIENT));
+ AutofillDataModel::INVALID,
+ profile.GetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::CLIENT));
// The dependent locality can't be validated, because we don't know the city,
// in the strict validation this is considered as invalid.
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profile.GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNSUPPORTED,
+ AutofillDataModel::CLIENT));
+ EXPECT_EQ(AutofillDataModel::UNSUPPORTED,
profile.GetValidityState(ADDRESS_HOME_STREET_ADDRESS,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
- profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
+ AutofillDataModel::VALID,
+ profile.GetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::CLIENT));
// Phone number is validated regardless of the country.
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profile.GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validator.cc b/chromium/components/autofill/core/browser/autofill_profile_validator.cc
index 35d0a46aa30..6a2744fc227 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validator.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validator.cc
@@ -14,7 +14,6 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
-#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_validation_util.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_validator.h"
@@ -39,14 +38,13 @@ AutofillProfileValidator::ValidationRequest::ValidationRequest(
base::WeakPtr<const AutofillProfile> profile,
autofill::AddressValidator* validator,
AutofillProfileValidatorCallback on_validated)
- : profile_(profile),
+ : profile_(*profile),
validator_(validator),
on_validated_(std::move(on_validated)),
has_responded_(false),
weak_factory_(this) {
on_timeout_.Reset(base::BindOnce(&ValidationRequest::OnRulesLoaded,
weak_factory_.GetWeakPtr()));
- DCHECK(profile_);
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, on_timeout_.callback(),
base::TimeDelta::FromSeconds(kRulesLoadingTimeoutSeconds));
@@ -63,12 +61,8 @@ void AutofillProfileValidator::ValidationRequest::OnRulesLoaded() {
return;
has_responded_ = true;
- if (!profile_)
- return;
-
- profile_validation_util::ValidateProfile(profile_.get(), validator_);
-
- std::move(on_validated_).Run(profile_.get());
+ profile_validation_util::ValidateProfile(&profile_, validator_);
+ std::move(on_validated_).Run(&profile_);
}
AutofillProfileValidator::AutofillProfileValidator(
@@ -102,7 +96,7 @@ void AutofillProfileValidator::StartProfileValidation(
// Start loading the rules for the region. If the rules were already in the
// process of being loaded, this call will do nothing.
- address_validator_.LoadRules(region_code);
+ LoadRulesForRegion(region_code);
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validator.h b/chromium/components/autofill/core/browser/autofill_profile_validator.h
index 52d88a8d677..2253b4d4498 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validator.h
+++ b/chromium/components/autofill/core/browser/autofill_profile_validator.h
@@ -14,14 +14,13 @@
#include "base/cancelable_callback.h"
#include "base/macros.h"
+#include "components/autofill/core/browser/autofill_profile.h"
#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
namespace autofill {
-class AutofillProfile;
-
using AutofillProfileValidatorCallback =
base::OnceCallback<void(const AutofillProfile*)>;
@@ -45,6 +44,13 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
void StartProfileValidation(const AutofillProfile* profile,
AutofillProfileValidatorCallback cb);
+ protected:
+ // Starts loading the rules for the specified |region_code|.
+ virtual void LoadRulesForRegion(const std::string& region_code);
+
+ // The address validator used to load rules.
+ AddressValidator address_validator_;
+
private:
// ValidationRequest loads Rules from the server and validates various fields
// in an autofill profile.
@@ -60,7 +66,7 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
void OnRulesLoaded();
private:
- base::WeakPtr<const AutofillProfile> profile_;
+ AutofillProfile profile_;
// Not owned. Outlives this object.
AddressValidator* validator_;
@@ -78,9 +84,6 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
// Returns whether the rules for the specified |region_code| is loaded.
bool AreRulesLoadedForRegion(const std::string& region_code);
- // Starts loading the rules for the specified |region_code|.
- void LoadRulesForRegion(const std::string& region_code);
-
// Implementation of the LoadRulesListener interface. Called when the address
// rules for the |region_code| have finished loading.
void OnAddressValidationRulesLoaded(const std::string& region_code,
@@ -90,9 +93,6 @@ class AutofillProfileValidator : public autofill::LoadRulesListener {
std::map<std::string, std::vector<std::unique_ptr<ValidationRequest>>>
pending_requests_;
- // The address validator used to load rules.
- AddressValidator address_validator_;
-
DISALLOW_COPY_AND_ASSIGN(AutofillProfileValidator);
};
diff --git a/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc
index 72a48f3fce4..34203afe788 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_validator_unittest.cc
@@ -87,7 +87,7 @@ class AutofillProfileValidatorTest : public testing::Test {
for (auto expectation : expected_validity_) {
EXPECT_EQ(expectation.second,
profile->GetValidityState(expectation.first,
- AutofillProfile::CLIENT));
+ AutofillDataModel::CLIENT));
}
}
@@ -101,7 +101,7 @@ class AutofillProfileValidatorTest : public testing::Test {
AutofillProfileValidatorCallback onvalidated_cb_;
- std::vector<std::pair<ServerFieldType, AutofillProfile::ValidityState>>
+ std::vector<std::pair<ServerFieldType, AutofillDataModel::ValidityState>>
expected_validity_;
private:
@@ -122,11 +122,14 @@ TEST_F(AutofillProfileValidatorTest, ValidateFullValidProfile_RulesNotLoaded) {
EXPECT_EQ(false, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -143,11 +146,11 @@ TEST_F(AutofillProfileValidatorTest, ValidateAddress_RulesLoaded) {
EXPECT_EQ(true, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -164,11 +167,12 @@ TEST_F(AutofillProfileValidatorTest,
EXPECT_EQ(false, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::INVALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::UNVALIDATED},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::UNVALIDATED},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -184,11 +188,11 @@ TEST_F(AutofillProfileValidatorTest, ValidateAddress_RuleNotExists) {
EXPECT_EQ(false, AreRulesLoadedForRegion(country_code));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::UNVALIDATED},
- {ADDRESS_HOME_ZIP, AutofillProfile::UNVALIDATED},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::UNVALIDATED},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::UNVALIDATED},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -203,11 +207,12 @@ TEST_F(AutofillProfileValidatorTest, ValidateAddress_EmptyCountryCode) {
// Set up the test expectations.
// The phone is validated for the US.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::EMPTY},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::UNVALIDATED},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::UNVALIDATED},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -220,11 +225,14 @@ TEST_F(AutofillProfileValidatorTest, StartProfileValidation_InvalidPhone) {
base::UTF8ToUTF16("Invalid Phone"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -236,11 +244,14 @@ TEST_F(AutofillProfileValidatorTest, StartProfileValidation_InvalidAddress) {
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Invalid State"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -254,11 +265,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Invalid State"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::EMPTY},
- {EMAIL_ADDRESS, AutofillProfile::VALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::EMPTY},
+ {EMAIL_ADDRESS, AutofillDataModel::VALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -272,11 +286,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("Invalid Zip"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -290,11 +307,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::UTF8ToUTF16("Invalid Zip"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::INVALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::EMPTY}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::INVALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::EMPTY}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -308,11 +328,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_ZIP, base::string16());
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::EMPTY},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::EMPTY},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -327,11 +350,14 @@ TEST_F(AutofillProfileValidatorTest,
base::UTF8ToUTF16("Invalid Phone"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -343,11 +369,14 @@ TEST_F(AutofillProfileValidatorTest, StartProfileValidation_InvalidEmail) {
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("Invalid Email"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::VALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::VALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::VALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::VALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
@@ -363,11 +392,14 @@ TEST_F(AutofillProfileValidatorTest,
profile.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("Invalid State"));
// Set up the test expectations.
- expected_validity_ = {{ADDRESS_HOME_COUNTRY, AutofillProfile::VALID},
- {ADDRESS_HOME_STATE, AutofillProfile::INVALID},
- {ADDRESS_HOME_ZIP, AutofillProfile::VALID},
- {PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID},
- {EMAIL_ADDRESS, AutofillProfile::INVALID}};
+ expected_validity_ = {
+ {ADDRESS_HOME_COUNTRY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_STATE, AutofillDataModel::INVALID},
+ {ADDRESS_HOME_CITY, AutofillDataModel::VALID},
+ {ADDRESS_HOME_DEPENDENT_LOCALITY, AutofillDataModel::EMPTY},
+ {ADDRESS_HOME_ZIP, AutofillDataModel::VALID},
+ {PHONE_HOME_WHOLE_NUMBER, AutofillDataModel::INVALID},
+ {EMAIL_ADDRESS, AutofillDataModel::INVALID}};
// Start the validator.
validator_->StartProfileValidation(&profile, std::move(onvalidated_cb_));
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
index f46ca53cf0c..22fc50b9595 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
@@ -28,7 +28,7 @@ namespace autofill {
AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
bool upload,
- bool should_request_name_from_user,
+ AutofillClient::SaveCreditCardOptions options,
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
AutofillClient::UploadSaveCardPromptCallback
@@ -38,7 +38,7 @@ AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
bool is_off_the_record)
: ConfirmInfoBarDelegate(),
upload_(upload),
- should_request_name_from_user_(should_request_name_from_user),
+ options_(options),
upload_save_card_prompt_callback_(
std::move(upload_save_card_prompt_callback)),
local_save_card_prompt_callback_(
@@ -59,7 +59,7 @@ AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
/*escape_apostrophes=*/true)) {
AutofillMetrics::LogCreditCardInfoBarMetric(
AutofillMetrics::INFOBAR_NOT_SHOWN_INVALID_LEGAL_MESSAGE, upload_,
- should_request_name_from_user_,
+ options_,
pref_service_->GetInteger(
prefs::kAutofillAcceptSaveCreditCardPromptState));
return;
@@ -67,7 +67,7 @@ AutofillSaveCardInfoBarDelegateMobile::AutofillSaveCardInfoBarDelegateMobile(
}
AutofillMetrics::LogCreditCardInfoBarMetric(
- AutofillMetrics::INFOBAR_SHOWN, upload_, should_request_name_from_user_,
+ AutofillMetrics::INFOBAR_SHOWN, upload_, options_,
pref_service_->GetInteger(
prefs::kAutofillAcceptSaveCreditCardPromptState));
}
@@ -153,7 +153,10 @@ base::string16 AutofillSaveCardInfoBarDelegateMobile::GetButtonLabel(
return base::string16();
}
- return should_request_name_from_user_
+ // Requesting name or expiration date from the user makes the save prompt a
+ // 2-step fix flow.
+ return options_.should_request_name_from_user ||
+ options_.should_request_expiration_date_from_user
? l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_CONTINUE)
: l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT);
}
@@ -178,7 +181,7 @@ void AutofillSaveCardInfoBarDelegateMobile::LogUserAction(
DCHECK(!had_user_interaction_);
AutofillMetrics::LogCreditCardInfoBarMetric(
- user_action, upload_, should_request_name_from_user_,
+ user_action, upload_, options_,
pref_service_->GetInteger(
prefs::kAutofillAcceptSaveCreditCardPromptState));
pref_service_->SetInteger(
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
index ed98a20297b..a99817a0ec5 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
+++ b/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
@@ -31,7 +31,7 @@ class AutofillSaveCardInfoBarDelegateMobile : public ConfirmInfoBarDelegate {
public:
AutofillSaveCardInfoBarDelegateMobile(
bool upload,
- bool should_request_name_from_user,
+ AutofillClient::SaveCreditCardOptions options,
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
AutofillClient::UploadSaveCardPromptCallback
@@ -84,8 +84,10 @@ class AutofillSaveCardInfoBarDelegateMobile : public ConfirmInfoBarDelegate {
// Whether the action is an upload or a local save.
bool upload_;
- // Whether the user should enter/confirm cardholder name.
- bool should_request_name_from_user_;
+ // If the cardholder name is missing, request the name from the user before
+ // saving the card. If the expiration date is missing, request the missing
+ // data from the user before saving the card.
+ AutofillClient::SaveCreditCardOptions options_;
// The callback to run once the user makes a decision with respect to the
// credit card upload offer-to-save prompt (if |upload_| is true).
diff --git a/chromium/components/autofill/core/browser/autofill_scanner.h b/chromium/components/autofill/core/browser/autofill_scanner.h
index 0babe38a2fd..a4826a522b2 100644
--- a/chromium/components/autofill/core/browser/autofill_scanner.h
+++ b/chromium/components/autofill/core/browser/autofill_scanner.h
@@ -46,7 +46,7 @@ class AutofillScanner {
size_t SaveCursor();
// This is only for logging purposes.
- size_t CursorIndex() { return static_cast<size_t>(cursor_ - begin_); };
+ size_t CursorIndex() { return static_cast<size_t>(cursor_ - begin_); }
private:
void Init(const std::vector<AutofillField*>& fields);
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.cc b/chromium/components/autofill/core/browser/autofill_test_utils.cc
index 9126d95ec29..ffab385a580 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.cc
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.cc
@@ -587,7 +587,7 @@ void InitializePossibleTypesAndValidities(
std::vector<ServerFieldTypeValidityStatesMap>&
possible_field_types_validities,
const std::vector<ServerFieldType>& possible_types,
- const std::vector<AutofillProfile::ValidityState>& validity_states) {
+ const std::vector<AutofillDataModel::ValidityState>& validity_states) {
possible_field_types.push_back(ServerFieldTypeSet());
possible_field_types_validities.push_back(ServerFieldTypeValidityStatesMap());
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.h b/chromium/components/autofill/core/browser/autofill_test_utils.h
index b67a11c3655..02eb5847a07 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.h
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.h
@@ -216,7 +216,7 @@ void InitializePossibleTypesAndValidities(
std::vector<ServerFieldTypeValidityStatesMap>&
possible_field_types_validities,
const std::vector<ServerFieldType>& possible_type,
- const std::vector<AutofillProfile::ValidityState>& validity_state = {});
+ const std::vector<AutofillDataModel::ValidityState>& validity_state = {});
// Fills the upload |field| with the information passed by parameter. If the
// value of a const char* parameter is NULL, the corresponding attribute won't
diff --git a/chromium/components/autofill/core/browser/autofill_type.cc b/chromium/components/autofill/core/browser/autofill_type.cc
index 3f2b48a3509..62bb3c04655 100644
--- a/chromium/components/autofill/core/browser/autofill_type.cc
+++ b/chromium/components/autofill/core/browser/autofill_type.cc
@@ -116,6 +116,7 @@ FieldTypeGroup GroupTypeOfServerFieldType(ServerFieldType field_type) {
case USERNAME:
return USERNAME_FIELD;
+ case PRICE:
case SEARCH_TERM:
return UNFILLABLE;
@@ -774,6 +775,8 @@ std::string AutofillType::ServerFieldTypeToString(ServerFieldType type) {
return "CONFIRMATION_PASSWORD";
case SEARCH_TERM:
return "SEARCH_TERM";
+ case PRICE:
+ return "PRICE";
case AMBIGUOUS_TYPE:
return "AMBIGUOUS_TYPE";
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
index 0459e25d4ff..7ad8b87e824 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
+++ b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
@@ -11,6 +11,7 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_service.h"
+#include "components/sync/base/data_type_histogram.h"
#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/sync_error.h"
@@ -24,6 +25,7 @@ AutofillWalletDataTypeController::AutofillWalletDataTypeController(
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service)
: AsyncDirectoryTypeController(type,
dump_stack,
@@ -31,6 +33,7 @@ AutofillWalletDataTypeController::AutofillWalletDataTypeController(
sync_client,
syncer::GROUP_DB,
std::move(db_thread)),
+ pdm_provider_(pdm_provider),
callback_registered_(false),
web_data_service_(web_data_service),
currently_enabled_(IsEnabled()) {
@@ -95,10 +98,14 @@ void AutofillWalletDataTypeController::StopModels() {
if (!sync_service()->CanSyncFeatureStart() ||
!sync_service()->GetPreferredDataTypes().Has(type()) ||
!currently_enabled_) {
- autofill::PersonalDataManager* pdm =
- sync_client()->GetPersonalDataManager();
- if (pdm)
+ autofill::PersonalDataManager* pdm = pdm_provider_.Run();
+ if (pdm) {
+ int count = pdm->GetServerCreditCards().size() +
+ pdm->GetServerProfiles().size() +
+ (pdm->GetPaymentsCustomerData() == nullptr ? 0 : 1);
+ SyncWalletDataRecordClearedEntitiesCount(count);
pdm->ClearAllServerData();
+ }
}
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
index 837d293a4be..be0e0fff83a 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
+++ b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
+#include "base/callback.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "components/prefs/pref_change_registrar.h"
@@ -12,7 +13,8 @@
namespace autofill {
class AutofillWebDataService;
-}
+class PersonalDataManager;
+} // namespace autofill
namespace syncer {
class SyncClient;
@@ -25,6 +27,9 @@ namespace browser_sync {
class AutofillWalletDataTypeController
: public syncer::AsyncDirectoryTypeController {
public:
+ using PersonalDataManagerProvider =
+ base::RepeatingCallback<autofill::PersonalDataManager*()>;
+
// |type| should be either AUTOFILL_WALLET or AUTOFILL_WALLET_METADATA.
// |dump_stack| is called when an unrecoverable error occurs.
AutofillWalletDataTypeController(
@@ -33,6 +38,7 @@ class AutofillWalletDataTypeController
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service);
~AutofillWalletDataTypeController() override;
@@ -51,6 +57,9 @@ class AutofillWalletDataTypeController
// Report an error (which will stop the datatype asynchronously).
void DisableForPolicy();
+ // Callback that allows accessing PersonalDataManager lazily.
+ const PersonalDataManagerProvider pdm_provider_;
+
// Whether the database loaded callback has been registered.
bool callback_registered_;
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc
index 1d391861d1b..c8a98aff248 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc
@@ -24,20 +24,21 @@
#include "components/sync/driver/configure_context.h"
#include "components/sync/driver/data_type_controller_mock.h"
#include "components/sync/driver/fake_generic_change_processor.h"
-#include "components/sync/driver/fake_sync_client.h"
#include "components/sync/driver/fake_sync_service.h"
-#include "components/sync/driver/sync_api_component_factory_mock.h"
+#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/fake_syncable_service.h"
#include "components/sync/model/sync_error.h"
#include "testing/gtest/include/gtest/gtest.h"
-using autofill::AutofillWebDataService;
-
namespace browser_sync {
namespace {
+using autofill::AutofillWebDataService;
+using testing::_;
+using testing::Return;
+
// Fake WebDataService implementation that stubs out the database loading.
class FakeWebDataService : public AutofillWebDataService {
public:
@@ -76,12 +77,9 @@ class FakeWebDataService : public AutofillWebDataService {
DISALLOW_COPY_AND_ASSIGN(FakeWebDataService);
};
-class AutofillWalletDataTypeControllerTest : public testing::Test,
- public syncer::FakeSyncClient {
+class AutofillWalletDataTypeControllerTest : public testing::Test {
public:
- AutofillWalletDataTypeControllerTest()
- : syncer::FakeSyncClient(&profile_sync_factory_),
- last_type_(syncer::UNSPECIFIED) {}
+ AutofillWalletDataTypeControllerTest() : last_type_(syncer::UNSPECIFIED) {}
~AutofillWalletDataTypeControllerTest() override {}
void SetUp() override {
@@ -90,12 +88,18 @@ class AutofillWalletDataTypeControllerTest : public testing::Test,
prefs_.registry()->RegisterBooleanPref(
autofill::prefs::kAutofillCreditCardEnabled, true);
+ ON_CALL(sync_client_, GetPrefService()).WillByDefault(Return(&prefs_));
+ ON_CALL(sync_client_, GetSyncableServiceForType(_))
+ .WillByDefault(Return(syncable_service_.AsWeakPtr()));
+
web_data_service_ = base::MakeRefCounted<FakeWebDataService>(
base::ThreadTaskRunnerHandle::Get(),
base::ThreadTaskRunnerHandle::Get());
autofill_wallet_dtc_ = std::make_unique<AutofillWalletDataTypeController>(
syncer::AUTOFILL_WALLET_DATA, base::ThreadTaskRunnerHandle::Get(),
- base::DoNothing(), &sync_service_, this, web_data_service_);
+ base::DoNothing(), &sync_service_, &sync_client_,
+ AutofillWalletDataTypeController::PersonalDataManagerProvider(),
+ web_data_service_);
last_type_ = syncer::UNSPECIFIED;
last_error_ = syncer::SyncError();
@@ -108,20 +112,12 @@ class AutofillWalletDataTypeControllerTest : public testing::Test,
syncable_service_.StopSyncing(syncer::AUTOFILL_WALLET_DATA);
}
- // FakeSyncClient overrides.
- PrefService* GetPrefService() override { return &prefs_; }
-
- base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
- syncer::ModelType type) override {
- return syncable_service_.AsWeakPtr();
- }
-
protected:
void SetStartExpectations() {
autofill_wallet_dtc_->SetGenericChangeProcessorFactoryForTest(
std::make_unique<syncer::FakeGenericChangeProcessorFactory>(
std::make_unique<syncer::FakeGenericChangeProcessor>(
- syncer::AUTOFILL_WALLET_DATA, this)));
+ syncer::AUTOFILL_WALLET_DATA)));
}
void Start() {
@@ -147,10 +143,10 @@ class AutofillWalletDataTypeControllerTest : public testing::Test,
TestingPrefServiceSimple prefs_;
syncer::FakeSyncService sync_service_;
syncer::StartCallbackMock start_callback_;
- syncer::SyncApiComponentFactoryMock profile_sync_factory_;
syncer::FakeSyncableService syncable_service_;
std::unique_ptr<AutofillWalletDataTypeController> autofill_wallet_dtc_;
scoped_refptr<FakeWebDataService> web_data_service_;
+ testing::NiceMock<syncer::SyncClientMock> sync_client_;
syncer::ModelType last_type_;
syncer::SyncError last_error_;
@@ -183,8 +179,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
EXPECT_EQ(syncer::DataTypeController::RUNNING, autofill_wallet_dtc_->state());
EXPECT_FALSE(last_error_.IsSet());
EXPECT_EQ(syncer::AUTOFILL_WALLET_DATA, last_type_);
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), false);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), true);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, false);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, true);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(last_error_.IsSet());
}
@@ -202,8 +198,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
EXPECT_EQ(syncer::DataTypeController::RUNNING, autofill_wallet_dtc_->state());
EXPECT_FALSE(last_error_.IsSet());
EXPECT_EQ(syncer::AUTOFILL_WALLET_DATA, last_type_);
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), true);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), false);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, true);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, false);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(last_error_.IsSet());
}
@@ -212,8 +208,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
DatatypeDisabledByWalletImportAtStartup) {
SetStartExpectations();
web_data_service_->LoadDatabase();
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), false);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), true);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, false);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, true);
EXPECT_EQ(syncer::DataTypeController::NOT_RUNNING,
autofill_wallet_dtc_->state());
Start();
@@ -225,8 +221,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
DatatypeDisabledByCreditCardsAtStartup) {
SetStartExpectations();
web_data_service_->LoadDatabase();
- autofill::prefs::SetPaymentsIntegrationEnabled(GetPrefService(), true);
- autofill::prefs::SetCreditCardAutofillEnabled(GetPrefService(), false);
+ autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, true);
+ autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, false);
EXPECT_EQ(syncer::DataTypeController::NOT_RUNNING,
autofill_wallet_dtc_->state());
Start();
diff --git a/chromium/components/autofill/core/browser/contact_form_label_formatter.cc b/chromium/components/autofill/core/browser/contact_form_label_formatter.cc
new file mode 100644
index 00000000000..47701675865
--- /dev/null
+++ b/chromium/components/autofill/core/browser/contact_form_label_formatter.cc
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/contact_form_label_formatter.h"
+
+namespace autofill {
+
+ContactFormLabelFormatter::ContactFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types,
+ const std::set<FieldTypeGroup>& field_type_groups)
+ : LabelFormatter(app_locale, focused_field_type, field_types),
+ field_type_groups_(field_type_groups),
+ filtered_field_type_groups_(field_type_groups) {
+ for (const ServerFieldType& type : field_types) {
+ if (type != focused_field_type) {
+ field_types_for_labels_.push_back(type);
+ }
+ }
+ const FieldTypeGroup group =
+ AutofillType(AutofillType(focused_field_type).GetStorableType()).group();
+ filtered_field_type_groups_.erase(group);
+}
+
+ContactFormLabelFormatter::~ContactFormLabelFormatter() {}
+
+std::vector<base::string16> ContactFormLabelFormatter::GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const {
+ // TODO(crbug.com/936168): Implement GetLabels().
+ std::vector<base::string16> labels;
+ return labels;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/contact_form_label_formatter.h b/chromium/components/autofill/core/browser/contact_form_label_formatter.h
new file mode 100644
index 00000000000..38684976af4
--- /dev/null
+++ b/chromium/components/autofill/core/browser/contact_form_label_formatter.h
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_CONTACT_FORM_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_CONTACT_FORM_LABEL_FORMATTER_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+
+// A LabelFormatter that creates Suggestions' disambiguating labels for forms
+// containing name and phone or email fields.
+class ContactFormLabelFormatter : public LabelFormatter {
+ public:
+ ContactFormLabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types,
+ const std::set<FieldTypeGroup>& field_type_groups);
+
+ ~ContactFormLabelFormatter() override;
+
+ std::vector<base::string16> GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const override;
+
+ private:
+ // A collection of field types that can be used to make labels. This
+ // collection excludes the focused_field_type_.
+ std::vector<ServerFieldType> field_types_for_labels_;
+
+ // A collection of meaningful FieldTypeGroups in the form with which the user
+ // is interacting.
+ std::set<FieldTypeGroup> field_type_groups_;
+
+ // A collection of meaningful FieldTypeGroups in the form with which the user
+ // is interacting minus the focused field's corresponding FieldTypeGroup.
+ std::set<FieldTypeGroup> filtered_field_type_groups_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CONTACT_FORM_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/contact_info_unittest.cc b/chromium/components/autofill/core/browser/contact_info_unittest.cc
index d07dfa041f1..3f2502fa654 100644
--- a/chromium/components/autofill/core/browser/contact_info_unittest.cc
+++ b/chromium/components/autofill/core/browser/contact_info_unittest.cc
@@ -46,7 +46,7 @@ TEST_P(SetFullNameTest, SetFullName) {
name.GetInfo(AutofillType(NAME_FULL), "en-US"));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
SetFullNameTest,
testing::Values(
@@ -215,7 +215,7 @@ struct ParsedNamesAreEqualTestCase {
starting_profile.ParsedNamesAreEqual(additional_profile));
}
- INSTANTIATE_TEST_CASE_P(
+ INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
ParsedNamesAreEqualTest,
testing::Values(
@@ -308,7 +308,7 @@ struct ParsedNamesAreEqualTestCase {
existing_name.GetRawInfo(NAME_FULL));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
OverwriteNameTest,
testing::Values(
@@ -387,7 +387,7 @@ struct NamePartsAreEmptyTestCase {
EXPECT_EQ(test_case.expected_result, name.NamePartsAreEmpty());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ContactInfoTest,
NamePartsAreEmptyTest,
testing::Values(NamePartsAreEmptyTestCase{"", "", "", "", true},
diff --git a/chromium/components/autofill/core/browser/credit_card.cc b/chromium/components/autofill/core/browser/credit_card.cc
index 139dca405e1..5d0273de71c 100644
--- a/chromium/components/autofill/core/browser/credit_card.cc
+++ b/chromium/components/autofill/core/browser/credit_card.cc
@@ -30,6 +30,7 @@
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_metadata.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_clock.h"
@@ -655,10 +656,30 @@ bool CreditCard::IsLocalDuplicateOfServerCard(const CreditCard& other) const {
}
bool CreditCard::HasSameNumberAs(const CreditCard& other) const {
- // For masked cards, this is the best we can do to compare card numbers.
+ // Masked cards are considered to have the same number if their last four
+ // digits match and if any expiration date information available for both
+ // cards matches.
if (record_type() == MASKED_SERVER_CARD ||
other.record_type() == MASKED_SERVER_CARD) {
- return NetworkAndLastFourDigits() == other.NetworkAndLastFourDigits();
+ bool last_four_digits_match = LastFourDigits() == other.LastFourDigits();
+ // The below metric is logged because this function previously compared
+ // cards' last four digits and networks if one card was masked. It may be
+ // useful to know how often networks match when the last four digits match.
+ // It is expected that when two cards' last four digits are the same, their
+ // networks will almost always match, too.
+ if (last_four_digits_match) {
+ AutofillMetrics::LogMaskedCardComparisonNetworksMatch(
+ NetworkForDisplay() == other.NetworkForDisplay());
+ }
+
+ bool months_match = expiration_month() == other.expiration_month() ||
+ expiration_month() == 0 ||
+ other.expiration_month() == 0;
+
+ bool years_match = expiration_year() == other.expiration_year() ||
+ expiration_year() == 0 || other.expiration_year() == 0;
+
+ return last_four_digits_match && months_match && years_match;
}
return StripSeparators(number_) == StripSeparators(other.number_);
@@ -869,7 +890,7 @@ base::string16 CreditCard::ExpirationMonthAsString() const {
if (expiration_month_ == 0)
return base::string16();
- base::string16 month = base::IntToString16(expiration_month_);
+ base::string16 month = base::NumberToString16(expiration_month_);
if (expiration_month_ >= 10)
return month;
@@ -882,7 +903,7 @@ base::string16 CreditCard::Expiration4DigitYearAsString() const {
if (expiration_year_ == 0)
return base::string16();
- return base::IntToString16(Expiration4DigitYear());
+ return base::NumberToString16(Expiration4DigitYear());
}
bool CreditCard::HasFirstAndLastName() const {
@@ -898,7 +919,7 @@ base::string16 CreditCard::Expiration2DigitYearAsString() const {
if (expiration_year_ == 0)
return base::string16();
- return base::IntToString16(Expiration2DigitYear());
+ return base::NumberToString16(Expiration2DigitYear());
}
void CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
diff --git a/chromium/components/autofill/core/browser/credit_card.h b/chromium/components/autofill/core/browser/credit_card.h
index deff6364ddc..397ac1bda06 100644
--- a/chromium/components/autofill/core/browser/credit_card.h
+++ b/chromium/components/autofill/core/browser/credit_card.h
@@ -165,7 +165,7 @@ class CreditCard : public AutofillDataModel {
bool IsLocalDuplicateOfServerCard(const CreditCard& other) const;
// Determines if |this| has the same number as |other|. If either is a masked
- // server card, compares the last four digits only.
+ // server card, compares their last four digits and expiration dates.
bool HasSameNumberAs(const CreditCard& other) const;
// Equality operators compare GUIDs, origins, and the contents.
diff --git a/chromium/components/autofill/core/browser/credit_card_field.cc b/chromium/components/autofill/core/browser/credit_card_field.cc
index fb1f8bf9914..cbf5de6d188 100644
--- a/chromium/components/autofill/core/browser/credit_card_field.cc
+++ b/chromium/components/autofill/core/browser/credit_card_field.cc
@@ -322,7 +322,7 @@ bool CreditCardField::LikelyCardYearSelectField(AutofillScanner* scanner) {
for (int year = time_exploded.year;
year < time_exploded.year + kYearsToMatch;
++year) {
- years_to_check.push_back(base::IntToString16(year));
+ years_to_check.push_back(base::NumberToString16(year));
}
return (FindConsecutiveStrings(years_to_check, field->option_values) ||
FindConsecutiveStrings(years_to_check, field->option_contents));
diff --git a/chromium/components/autofill/core/browser/credit_card_field_unittest.cc b/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
index f701a390212..35ee3dba298 100644
--- a/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_field_unittest.cc
@@ -375,7 +375,7 @@ TEST_P(ParseExpFieldTest, ParseExpField) {
field_candidates_map_[ASCIIToUTF16("exp3")].BestHeuristicType());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardFieldTest,
ParseExpFieldTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager.cc b/chromium/components/autofill/core/browser/credit_card_save_manager.cc
index cef57c082f9..910d5e02fd6 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager.cc
+++ b/chromium/components/autofill/core/browser/credit_card_save_manager.cc
@@ -15,6 +15,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
@@ -87,7 +88,9 @@ CreditCardSaveManager::CreditCardSaveManager(
// This is to initialize StrikeDatabase is if it hasn't been already, so that
// its cache would be loaded and ready to use when the first CCSM is created.
if (base::FeatureList::IsEnabled(
- features::kAutofillSaveCreditCardUsesStrikeSystemV2)) {
+ features::kAutofillSaveCreditCardUsesStrikeSystemV2) ||
+ base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
// Only init when |kAutofillSaveCreditCardUsesStrikeSystemV2| is enabled. If
// flag is off and LegacyStrikeDatabase instead of StrikeDatabase is used,
// this init will cause failure on GetStrikes().
@@ -98,9 +101,11 @@ CreditCardSaveManager::CreditCardSaveManager(
CreditCardSaveManager::~CreditCardSaveManager() {}
void CreditCardSaveManager::AttemptToOfferCardLocalSave(
+ bool has_non_focusable_field,
const CreditCard& card) {
local_card_save_candidate_ = card;
show_save_prompt_ = base::nullopt;
+ has_non_focusable_field_ = has_non_focusable_field;
// Query the Autofill StrikeDatabase on if we should pop up the
// offer-to-save prompt for this card.
@@ -125,6 +130,7 @@ void CreditCardSaveManager::AttemptToOfferCardLocalSave(
void CreditCardSaveManager::AttemptToOfferCardUploadSave(
const FormStructure& submitted_form,
+ bool has_non_focusable_field,
const CreditCard& card,
const bool uploading_local_card) {
// Abort the uploading if |payments_client_| is nullptr.
@@ -151,6 +157,8 @@ void CreditCardSaveManager::AttemptToOfferCardUploadSave(
found_value_in_cvc_field_ = false;
found_cvc_value_in_non_cvc_field_ = false;
+ has_non_focusable_field_ = has_non_focusable_field;
+
for (const auto& field : submitted_form) {
const bool is_valid_cvc = IsValidCreditCardSecurityCode(
field->value, upload_request_.card.network());
@@ -175,6 +183,11 @@ void CreditCardSaveManager::AttemptToOfferCardUploadSave(
pending_upload_request_origin_ = submitted_form.main_frame_origin();
+ if (has_non_focusable_field_) {
+ upload_decision_metrics_ |=
+ AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD;
+ }
+
if (upload_request_.cvc.empty()) {
// Apply the CVC decision to |upload_decision_metrics_| to denote a problem
// was found.
@@ -328,7 +341,9 @@ void CreditCardSaveManager::OnDidUploadCard(
/*is_local=*/false,
GetCreditCardSaveStrikeDatabase()->GetStrikes(
base::UTF16ToUTF8(upload_request_.card.LastFourDigits())));
- // Clear all strikes for this card, in case it is later removed.
+
+ // Clear all CreditCardSave strikes for this card, in case it is later
+ // removed.
GetCreditCardSaveStrikeDatabase()->ClearStrikes(
base::UTF16ToUTF8(upload_request_.card.LastFourDigits()));
} else if (base::FeatureList::IsEnabled(
@@ -377,11 +392,22 @@ void CreditCardSaveManager::OnDidUploadCard(
CreditCardSaveStrikeDatabase*
CreditCardSaveManager::GetCreditCardSaveStrikeDatabase() {
- if (strike_database_.get() == nullptr) {
- strike_database_ = std::make_unique<CreditCardSaveStrikeDatabase>(
- CreditCardSaveStrikeDatabase(client_->GetStrikeDatabase()));
+ if (credit_card_save_strike_database_.get() == nullptr) {
+ credit_card_save_strike_database_ =
+ std::make_unique<CreditCardSaveStrikeDatabase>(
+ CreditCardSaveStrikeDatabase(client_->GetStrikeDatabase()));
}
- return strike_database_.get();
+ return credit_card_save_strike_database_.get();
+}
+
+LocalCardMigrationStrikeDatabase*
+CreditCardSaveManager::GetLocalCardMigrationStrikeDatabase() {
+ if (local_card_migration_strike_database_.get() == nullptr) {
+ local_card_migration_strike_database_ =
+ std::make_unique<LocalCardMigrationStrikeDatabase>(
+ LocalCardMigrationStrikeDatabase(client_->GetStrikeDatabase()));
+ }
+ return local_card_migration_strike_database_.get();
}
void CreditCardSaveManager::OnDidGetStrikesForLocalSave(const int num_strikes) {
@@ -396,8 +422,8 @@ void CreditCardSaveManager::OnDidGetStrikesForUploadSave(
show_save_prompt_ =
num_strikes < kMaxStrikesToPreventPoppingUpOfferToSavePrompt;
- // Only offer upload once both Payments and the Autofill LegacyStrikeDatabase
- // have returned their decisions. Use population of
+ // Only offer upload once both Payments and the Autofill
+ // LegacyStrikeDatabase have returned their decisions. Use population of
// |upload_request_.context_token| as an indicator of the Payments call
// returning successfully.
if (!upload_request_.context_token.empty())
@@ -407,12 +433,24 @@ void CreditCardSaveManager::OnDidGetStrikesForUploadSave(
void CreditCardSaveManager::OnDidGetUploadDetails(
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
if (observer_for_testing_)
observer_for_testing_->OnReceivedGetUploadDetailsResponse();
if (result == AutofillClient::SUCCESS) {
// Do *not* call payments_client_->Prepare() here. We shouldn't send
// credentials until the user has explicitly accepted a prompt to upload.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillDoNotUploadSaveUnsupportedCards) &&
+ !supported_card_bin_ranges.empty() &&
+ !IsCreditCardSupported(supported_card_bin_ranges)) {
+ AttemptToOfferCardLocalSave(has_non_focusable_field_,
+ upload_request_.card);
+ upload_decision_metrics_ |=
+ AutofillMetrics::UPLOAD_NOT_OFFERED_UNSUPPORTED_BIN_RANGE;
+ LogCardUploadDecisions(upload_decision_metrics_);
+ return;
+ }
upload_request_.context_token = context_token;
legal_message_ = base::DictionaryValue::From(std::move(legal_message));
@@ -445,8 +483,10 @@ void CreditCardSaveManager::OnDidGetUploadDetails(
upload_request_.detected_values & DetectedValue::ADDRESS_NAME) &&
upload_request_.detected_values & DetectedValue::POSTAL_CODE &&
upload_request_.detected_values & DetectedValue::CVC;
- if (found_name_and_postal_code_and_cvc && !uploading_local_card_)
- AttemptToOfferCardLocalSave(upload_request_.card);
+ if (found_name_and_postal_code_and_cvc && !uploading_local_card_) {
+ AttemptToOfferCardLocalSave(has_non_focusable_field_,
+ upload_request_.card);
+ }
upload_decision_metrics_ |=
AutofillMetrics::UPLOAD_NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED;
LogCardUploadDecisions(upload_decision_metrics_);
@@ -467,7 +507,9 @@ void CreditCardSaveManager::OfferCardLocalSave() {
if (observer_for_testing_)
observer_for_testing_->OnOfferLocalSave();
client_->ConfirmSaveCreditCardLocally(
- local_card_save_candidate_, show_save_prompt_.value(),
+ local_card_save_candidate_,
+ AutofillClient::SaveCreditCardOptions().with_show_prompt(
+ show_save_prompt_.value()),
base::BindOnce(&CreditCardSaveManager::OnUserDidDecideOnLocalSave,
weak_ptr_factory_.GetWeakPtr()));
@@ -488,17 +530,19 @@ void CreditCardSaveManager::OfferCardUploadSave() {
#else
bool is_mobile_build = false;
#endif // #if defined(OS_ANDROID) || defined(OS_IOS)
-
// If |show_save_prompt_.value()| is false, desktop builds will still offer
// save in the omnibox without popping-up the bubble. Mobile builds, however,
// should not display the offer-to-save infobar at all.
if (!is_mobile_build || show_save_prompt_.value()) {
user_did_accept_upload_prompt_ = false;
-
client_->ConfirmSaveCreditCardToCloud(
upload_request_.card, std::move(legal_message_),
- should_request_name_from_user_,
- should_request_expiration_date_from_user_, show_save_prompt_.value(),
+ AutofillClient::SaveCreditCardOptions()
+ .with_has_non_focusable_field(has_non_focusable_field_)
+ .with_should_request_name_from_user(should_request_name_from_user_)
+ .with_should_request_expiration_date_from_user(
+ should_request_expiration_date_from_user_)
+ .with_show_prompt(show_save_prompt_.value()),
base::BindOnce(&CreditCardSaveManager::OnUserDidDecideOnUploadSave,
weak_ptr_factory_.GetWeakPtr()));
client_->LoadRiskData(
@@ -537,12 +581,13 @@ void CreditCardSaveManager::OnUserDidDecideOnLocalSave(
/*is_local=*/true);
if (base::FeatureList::IsEnabled(
features::kAutofillSaveCreditCardUsesStrikeSystemV2)) {
- // Log how many strikes the card had when it was saved.
+ // Log how many CreditCardSave strikes the card had when it was saved.
LogStrikesPresentWhenCardSaved(
/*is_local=*/true,
GetCreditCardSaveStrikeDatabase()->GetStrikes(base::UTF16ToUTF8(
local_card_save_candidate_.LastFourDigits())));
- // Clear all strikes for this card, in case it is later removed.
+ // Clear all CreditCardSave strikes for this card, in case it is later
+ // removed.
GetCreditCardSaveStrikeDatabase()->ClearStrikes(
base::UTF16ToUTF8(local_card_save_candidate_.LastFourDigits()));
} else if (base::FeatureList::IsEnabled(
@@ -563,6 +608,12 @@ void CreditCardSaveManager::OnUserDidDecideOnLocalSave(
base::UTF16ToUTF8(local_card_save_candidate_.LastFourDigits())),
base::DoNothing());
}
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
+ GetLocalCardMigrationStrikeDatabase()->RemoveStrikes(
+ LocalCardMigrationStrikeDatabase::
+ kStrikesToRemoveWhenLocalCardAdded);
+ }
personal_data_manager_->OnAcceptedLocalCreditCardSave(
local_card_save_candidate_);
@@ -818,12 +869,19 @@ void CreditCardSaveManager::OnUserDidDecideOnUploadSave(
const AutofillClient::UserProvidedCardDetails& user_provided_card_details) {
switch (user_decision) {
case AutofillClient::ACCEPTED:
-// On Android, requesting cardholder name is a two step flow.
+// On Android, requesting cardholder name or expiration date is a two step
+// flow.
#if defined(OS_ANDROID)
if (should_request_name_from_user_) {
client_->ConfirmAccountNameFixFlow(base::BindOnce(
&CreditCardSaveManager::OnUserDidAcceptAccountNameFixFlow,
weak_ptr_factory_.GetWeakPtr()));
+ } else if (should_request_expiration_date_from_user_) {
+ client_->ConfirmExpirationDateFixFlow(
+ upload_request_.card,
+ base::BindOnce(
+ &CreditCardSaveManager::OnUserDidAcceptExpirationDateFixFlow,
+ weak_ptr_factory_.GetWeakPtr()));
} else {
OnUserDidAcceptUploadHelper(user_provided_card_details);
}
@@ -850,6 +908,13 @@ void CreditCardSaveManager::OnUserDidAcceptAccountNameFixFlow(
/*expiration_date_month=*/base::string16(),
/*expiration_date_year=*/base::string16()});
}
+
+void CreditCardSaveManager::OnUserDidAcceptExpirationDateFixFlow(
+ const base::string16& month,
+ const base::string16& year) {
+ OnUserDidAcceptUploadHelper(
+ {/*cardholder_name=*/base::string16(), month, year});
+}
#endif
void CreditCardSaveManager::OnUserDidAcceptUploadHelper(
@@ -913,7 +978,7 @@ void CreditCardSaveManager::SendUploadCardRequest() {
void CreditCardSaveManager::OnUserDidIgnoreOrDeclineSave(
const base::string16& card_last_four_digits) {
- if (show_save_prompt_.value()) {
+ if (show_save_prompt_ != base::nullopt && show_save_prompt_.value()) {
if (base::FeatureList::IsEnabled(
features::kAutofillSaveCreditCardUsesStrikeSystemV2)) {
// If the user rejected or ignored save and the offer-to-save bubble or
@@ -1005,4 +1070,28 @@ void CreditCardSaveManager::LogSaveCardRequestExpirationDateReasonMetric() {
}
}
+bool CreditCardSaveManager::IsCreditCardSupported(
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
+ base::string16 stripped_number =
+ CreditCard::StripSeparators(upload_request_.card.number());
+ for (auto& bin_range : supported_card_bin_ranges) {
+ unsigned long range_num_of_digits =
+ base::NumberToString(bin_range.first).size();
+ DCHECK_EQ(range_num_of_digits,
+ base::NumberToString(bin_range.second).size());
+ // The first n digits of credit card number, where n is the number of
+ // digits in range's starting/ending number.
+ int first_digits_start, first_digits_end;
+ base::StringToInt(stripped_number.substr(0, range_num_of_digits),
+ &first_digits_start);
+ base::StringToInt(stripped_number.substr(0, range_num_of_digits),
+ &first_digits_end);
+ if (first_digits_start >= bin_range.first &&
+ first_digits_end <= bin_range.second) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager.h b/chromium/components/autofill/core/browser/credit_card_save_manager.h
index a1ae70e31ff..5cffff6e8c9 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager.h
+++ b/chromium/components/autofill/core/browser/credit_card_save_manager.h
@@ -8,6 +8,7 @@
#include <map>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "base/optional.h"
@@ -18,6 +19,7 @@
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/credit_card_save_strike_database.h"
#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/local_card_migration_strike_database.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "url/origin.h"
@@ -93,11 +95,18 @@ class CreditCardSaveManager {
virtual ~CreditCardSaveManager();
// Begins the process to offer local credit card save to the user.
- void AttemptToOfferCardLocalSave(const CreditCard& card);
+ // If |has_non_focusable_field| is true, the save is triggered by a form that
+ // has non_focusable fields.
+ void AttemptToOfferCardLocalSave(bool has_non_focusable_field,
+ const CreditCard& card);
// Begins the process to offer upload credit card save to the user if the
// imported card passes all requirements and Google Payments approves.
+ // If |has_non_focusable_field| is true, the save is triggered by a form that
+ // has non-focusable fields. if |uploading_local_card| is true, the card being
+ // offered for upload is already a local card on the device.
void AttemptToOfferCardUploadSave(const FormStructure& submitted_form,
+ bool has_non_focusable_field,
const CreditCard& card,
const bool uploading_local_card);
@@ -124,12 +133,17 @@ class CreditCardSaveManager {
private:
friend class CreditCardSaveManagerTest;
friend class CreditCardSaveManagerTestObserverBridge;
+ friend class LocalCardMigrationBrowserTest;
friend class TestCreditCardSaveManager;
friend class SaveCardBubbleViewsFullFormBrowserTest;
+ friend class SaveCardInfobarEGTestHelper;
// Returns the CreditCardSaveStrikeDatabase for |client_|.
CreditCardSaveStrikeDatabase* GetCreditCardSaveStrikeDatabase();
+ // Returns the GetLocalCardMigrationStrikeDatabase for |client_|.
+ LocalCardMigrationStrikeDatabase* GetLocalCardMigrationStrikeDatabase();
+
// Sets |show_save_prompt| and moves forward with offering credit card local
// save.
void OnDidGetStrikesForLocalSave(const int num_strikes);
@@ -140,10 +154,14 @@ class CreditCardSaveManager {
// Returns the legal message retrieved from Payments. On failure or not
// meeting Payments's conditions for upload, |legal_message| will contain
- // nullptr.
- void OnDidGetUploadDetails(AutofillClient::PaymentsRpcResult result,
- const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message);
+ // nullptr. |supported_card_bin_ranges| is a list of BIN prefix ranges which
+ // are supoorted, with the first and second number in the pair being the start
+ // and end of the range.
+ void OnDidGetUploadDetails(
+ AutofillClient::PaymentsRpcResult result,
+ const base::string16& context_token,
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges);
// Logs the number of strikes that a card had when save succeeded.
void LogStrikesPresentWhenCardSaved(bool is_local, const int num_strikes);
@@ -196,12 +214,16 @@ class CreditCardSaveManager {
user_provided_card_details);
#if defined(OS_ANDROID)
- // Sets |user_did_accept_upload_prompt_| and calls SendUploadCardRequest if
- // the risk data is available. Sets the cardholder name on the upload request
- // if |cardholder_name| is set.
+ // Upload the card details with the user provided cardholder_name.
// Only relevant for mobile as fix flow is two steps on mobile compared to
// one step on desktop.
void OnUserDidAcceptAccountNameFixFlow(const base::string16& cardholder_name);
+
+ // Upload the card details with the user provided expiration date month and
+ // year. Only relevant for mobile as fix flow is two steps on mobile compared
+ // to one step on desktop.
+ void OnUserDidAcceptExpirationDateFixFlow(const base::string16& month,
+ const base::string16& year);
#endif // defined(OS_ANDROID)
// Helper function that calls SendUploadCardRequest by setting
@@ -242,6 +264,13 @@ class CreditCardSaveManager {
// Logs the reason why expiration date was explicitly requested.
void LogSaveCardRequestExpirationDateReasonMetric();
+ // Checks if credit card matches one of the ranges in
+ // |supported_card_bin_ranges|, inclusive of the start and end boundaries.
+ // For example, if the range consists of std::pair<34, 36>, then all cards
+ // with first two digits of 34, 35 and 36 are supported.
+ bool IsCreditCardSupported(
+ std::vector<std::pair<int, int>> supported_card_bin_ranges);
+
// For testing.
void SetEventObserverForTesting(ObserverForTest* observer) {
observer_for_testing_ = observer;
@@ -302,12 +331,22 @@ class CreditCardSaveManager {
// determined to be a CVC field via heuristics has a valid CVC |value|.
bool found_cvc_value_in_non_cvc_field_ = false;
+ // |has_non_focusable_field_| is |true| if there exists a field that
+ // |is_focusable| is false.
+ bool has_non_focusable_field_ = false;
+
// The origin of the top level frame from which a form is uploaded.
url::Origin pending_upload_request_origin_;
// The returned legal message from a GetUploadDetails call to Google Payments.
std::unique_ptr<base::DictionaryValue> legal_message_;
+ std::unique_ptr<CreditCardSaveStrikeDatabase>
+ credit_card_save_strike_database_;
+
+ std::unique_ptr<LocalCardMigrationStrikeDatabase>
+ local_card_migration_strike_database_;
+
std::unique_ptr<CreditCardSaveStrikeDatabase> strike_database_;
// May be null.
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc b/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc
index ef3e151e073..d4d246aaf5f 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc
@@ -117,7 +117,6 @@ class CreditCardSaveManagerTest : public testing::Test {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/false);
personal_data_.SetSyncServiceForTest(&sync_service_);
autocomplete_history_manager_.Init(
@@ -183,7 +182,8 @@ class CreditCardSaveManagerTest : public testing::Test {
void CreateTestCreditCardFormData(FormData* form,
bool is_https,
bool use_month_type,
- bool split_names = false) {
+ bool split_names = false,
+ bool is_from_non_focusable_form = false) {
form->name = ASCIIToUTF16("MyForm");
if (is_https) {
form->origin = GURL("https://myform.com/form.html");
@@ -214,6 +214,7 @@ class CreditCardSaveManagerTest : public testing::Test {
form->fields.push_back(field);
}
test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field);
+ field.is_focusable = !is_from_non_focusable_form;
form->fields.push_back(field);
if (use_month_type) {
test::CreateTestFormField("Expiration Date", "ccmonth", "", "month",
@@ -756,6 +757,170 @@ TEST_F(CreditCardSaveManagerTest,
"Autofill.SaveCardReachedPersonalDataManager.Server", 0);
}
+// Tests metrics for supporting unfocused card form.
+TEST_F(CreditCardSaveManagerTest, UploadCreditCard_WithNonFocusableField) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
+ // Verify that the correct histogram entries were logged.
+ ExpectCardUploadDecision(histogram_tester, AutofillMetrics::UPLOAD_OFFERED);
+ ExpectCardUploadDecision(
+ histogram_tester,
+ AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD);
+ // Verify that the correct UKM was logged.
+ ExpectCardUploadDecisionUkm(
+ AutofillMetrics::UPLOAD_OFFERED |
+ AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD);
+}
+
+// Tests upload card save will still work as usual when supporting unfocused
+// card form experiment is off.
+TEST_F(CreditCardSaveManagerTest,
+ UploadCreditCard_WithNonFocusableField_ExpOff) {
+ scoped_feature_list_.InitAndDisableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
+// Tests local card save will still work as usual when supporting unfocused card
+// form feature is already on.
+TEST_F(CreditCardSaveManagerTest, LocalCreditCard_WithNonFocusableField) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(false);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
+// Tests local card save will still work as usual when supporting unfocused card
+// form experiment is off.
+TEST_F(CreditCardSaveManagerTest,
+ LocalCreditCard_WithNonFocusableField_ExpOff) {
+ scoped_feature_list_.InitAndDisableFeature(
+ features::kAutofillImportNonFocusableCreditCardForms);
+ credit_card_save_manager_->SetCreditCardUploadEnabled(false);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with non_focusable form field.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true,
+ /*is_from_non_focusable_form=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
// Tests that a credit card inferred from a form with a credit card first and
// last name can be uploaded.
TEST_F(CreditCardSaveManagerTest, UploadCreditCard_FirstAndLastName) {
@@ -2831,7 +2996,7 @@ TEST_F(CreditCardSaveManagerTest, DuplicateMaskedCreditCard_NoUpload) {
}
// This class is parametrized to allow running all the inheriting tests with and
-// without a specific feature enabled. See INSTANTIATE_TEST_CASE_P.
+// without a specific feature enabled. See INSTANTIATE_TEST_SUITE_P.
class CreditCardSaveManagerFeatureParameterizedTest
: public CreditCardSaveManagerTest,
public ::testing::WithParamInterface<
@@ -3928,9 +4093,9 @@ TEST_P(CreditCardSaveManagerFeatureParameterizedTest,
// Feature disabled
// CreditCardSaveManagerFeatureParameterizedTest.NothingIfNothingFound/1:
// Feature enabled.
-INSTANTIATE_TEST_CASE_P(, // Empty instatiation name.
- CreditCardSaveManagerFeatureParameterizedTest,
- ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(, // Empty instatiation name.
+ CreditCardSaveManagerFeatureParameterizedTest,
+ ::testing::Values(false, true));
TEST_F(CreditCardSaveManagerTest,
UploadCreditCard_DoNotAddAnyFlagStatesToRequestIfExperimentsOff) {
@@ -5232,4 +5397,171 @@ TEST_F(CreditCardSaveManagerTest, OnUserDidAcceptUpload_NotifiesPDM) {
UserHasAcceptedUpload({});
}
+// Tests that 2 LocalCardMigrationStrikes are removed when cards are saved
+// locally.
+TEST_F(CreditCardSaveManagerTest,
+ LocalCreditCard_LocalCardMigrationStrikesRemovedOnLocalSave) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+
+ // Start with 3 strikes in |local_card_migration_strike_database|.
+ local_card_migration_strike_database.AddStrikes(3);
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+
+ credit_card_save_manager_->SetCreditCardUploadEnabled(false);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with credit card first and last name
+ // fields.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+
+ // 2 strikes should be removed when card was saved locally.
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 1);
+}
+
+// Tests that no LocalCardMigrationStrikes get removed due to cards being
+// uploaded.
+TEST_F(CreditCardSaveManagerTest,
+ UploadCreditCard_NoLocalSaveMigrationStrikesRemovedOnUpload) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+
+ // Start with 3 strikes in |local_card_migration_strike_database|.
+ local_card_migration_strike_database.AddStrikes(3);
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+
+ credit_card_save_manager_->SetCreditCardUploadEnabled(true);
+
+ // Create, fill and submit an address form in order to establish a recent
+ // profile which can be selected for the upload request.
+ FormData address_form;
+ test::CreateTestAddressFormData(&address_form);
+ FormsSeen(std::vector<FormData>(1, address_form));
+ ExpectUniqueFillableFormParsedUkm();
+
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+
+ // Set up our credit card form data with credit card first and last name
+ // fields.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*use_month_type=*/false, /*split_names=*/true);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo");
+ credit_card_form.fields[1].value = ASCIIToUTF16("Master");
+ credit_card_form.fields[2].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[4].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[5].value = ASCIIToUTF16("123");
+
+ base::HistogramTester histogram_tester;
+
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
+
+ // Strike count shouldn't change.
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+}
+
+// Tests that if a card doesn't fall in any of the supported bin ranges, local
+// save is offered rather than upload save.
+TEST_F(CreditCardSaveManagerTest, UploadSaveNotOfferedForUnsupportedCard) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillDoNotUploadSaveUnsupportedCards);
+ std::vector<std::pair<int, int>> supported_card_bin_ranges{
+ std::make_pair(4111, 4113), std::make_pair(34, 34),
+ std::make_pair(300, 305)};
+ payments_client_->SetSupportedBINRanges(supported_card_bin_ranges);
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("5454545454545454");
+ credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ // Since card isn't in any of the supported ranges, local save should be
+ // offered and upload save should not.
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
+// Tests that if a card falls in one of the supported bin ranges, upload save
+// is offered.
+TEST_F(CreditCardSaveManagerTest, UploadSaveOfferedForSupportedCard) {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillDoNotUploadSaveUnsupportedCards);
+ // Set supported BIN ranges.
+ std::vector<std::pair<int, int>> supported_card_bin_ranges{
+ std::make_pair(4111, 4113)};
+ payments_client_->SetSupportedBINRanges(supported_card_bin_ranges);
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
+ credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111");
+ credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
+ credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
+ credit_card_form.fields[4].value = ASCIIToUTF16("123");
+
+ // Since card is in one of the supported ranges(4111-4113), upload save should
+ // be offered.
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc b/chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc
deleted file mode 100644
index 6628663394c..00000000000
--- a/chromium/components/autofill/core/browser/credit_card_save_strike_database_unittest.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill/core/browser/credit_card_save_strike_database.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/autofill/core/browser/proto/strike_data.pb.h"
-#include "components/autofill/core/browser/test_autofill_clock.h"
-#include "components/autofill/core/browser/test_credit_card_save_strike_database.h"
-#include "components/autofill/core/common/autofill_clock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace autofill {
-
-class CreditCardSaveStrikeDatabaseTest : public ::testing::Test {
- public:
- CreditCardSaveStrikeDatabaseTest()
- : strike_database_(new StrikeDatabase(InitFilePath())) {}
-
- protected:
- base::HistogramTester* GetHistogramTester() { return &histogram_tester_; }
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- TestCreditCardSaveStrikeDatabase strike_database_;
-
- private:
- static const base::FilePath InitFilePath() {
- base::ScopedTempDir temp_dir_;
- EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
- const base::FilePath file_path =
- temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest");
- return file_path;
- }
-
- base::HistogramTester histogram_tester_;
-};
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, GetKeyForCreditCardSaveTest) {
- const std::string last_four = "1234";
- EXPECT_EQ("CreditCardSave__1234", strike_database_.GetKey(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, MaxStrikesLimitReachedTest) {
- const std::string last_four = "1234";
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four));
- // 1st strike added for |last_four|.
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four));
- // 2nd strike added for |last_four|.
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(last_four));
- // 3rd strike added for |last_four|.
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest,
- CreditCardSaveNthStrikeAddedHistogram) {
- const std::string last_four1 = "1234";
- const std::string last_four2 = "9876";
- // 1st strike added for |last_four1|.
- strike_database_.AddStrike(last_four1);
- // 2nd strike added for |last_four1|.
- strike_database_.AddStrike(last_four1);
- // 1st strike added for |last_four2|.
- strike_database_.AddStrike(last_four2);
- std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
- "Autofill.StrikeDatabase.NthStrikeAdded.CreditCardSave");
- // There should be two buckets, one for 1st strike, one for 2nd strike count.
- ASSERT_EQ(2U, buckets.size());
- // Both |last_four1| and |last_four2| have 1st strikes recorded.
- EXPECT_EQ(2, buckets[0].count);
- // Only |last_four1| has 2nd strike recorded.
- EXPECT_EQ(1, buckets[1].count);
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest,
- AddStrikeForZeroAndNonZeroStrikesTest) {
- const std::string last_four = "1234";
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four));
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(1, strike_database_.GetStrikes(last_four));
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(2, strike_database_.GetStrikes(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, ClearStrikesForNonZeroStrikesTest) {
- const std::string last_four = "1234";
- strike_database_.AddStrike(last_four);
- EXPECT_EQ(1, strike_database_.GetStrikes(last_four));
- strike_database_.ClearStrikes(last_four);
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, ClearStrikesForZeroStrikesTest) {
- const std::string last_four = "1234";
- strike_database_.ClearStrikes(last_four);
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four));
-}
-
-TEST_F(CreditCardSaveStrikeDatabaseTest, RemoveExpiredStrikesTest) {
- autofill::TestAutofillClock test_clock;
- test_clock.SetNow(AutofillClock::Now());
- const std::string last_four1 = "1234";
- const std::string last_four2 = "9876";
- strike_database_.AddStrike(last_four1);
-
- // Advance clock to past the entry for |last_four1|'s expiry time.
- test_clock.Advance(base::TimeDelta::FromMicroseconds(
- strike_database_.GetExpiryTimeMicros() + 1));
-
- strike_database_.AddStrike(last_four2);
- strike_database_.RemoveExpiredStrikes();
-
- // |last_four1|'s entry should have its most recent strike expire, but
- // |last_four2|'s should not.
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four1));
- EXPECT_EQ(1, strike_database_.GetStrikes(last_four2));
-
- // Advance clock to past |last_four2|'s expiry time.
- test_clock.Advance(base::TimeDelta::FromMicroseconds(
- strike_database_.GetExpiryTimeMicros() + 1));
-
- strike_database_.RemoveExpiredStrikes();
-
- // |last_four1| and |last_four2| should have no more unexpired strikes.
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four1));
- EXPECT_EQ(0, strike_database_.GetStrikes(last_four2));
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/credit_card_unittest.cc b/chromium/components/autofill/core/browser/credit_card_unittest.cc
index 9552cae6cd4..71153c60fab 100644
--- a/chromium/components/autofill/core/browser/credit_card_unittest.cc
+++ b/chromium/components/autofill/core/browser/credit_card_unittest.cc
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_experiments.h"
@@ -364,19 +365,19 @@ TEST_P(SetExpirationYearFromStringTest, SetExpirationYearFromString) {
<< test_case.expiration_year << " " << test_case.expected_year;
}
-INSTANTIATE_TEST_CASE_P(CreditCardTest,
- SetExpirationYearFromStringTest,
- testing::Values(
- // Valid values.
- SetExpirationYearFromStringTestCase{"2040", 2040},
- SetExpirationYearFromStringTestCase{"45", 2045},
- SetExpirationYearFromStringTestCase{"045", 2045},
- SetExpirationYearFromStringTestCase{"9", 2009},
+INSTANTIATE_TEST_SUITE_P(CreditCardTest,
+ SetExpirationYearFromStringTest,
+ testing::Values(
+ // Valid values.
+ SetExpirationYearFromStringTestCase{"2040", 2040},
+ SetExpirationYearFromStringTestCase{"45", 2045},
+ SetExpirationYearFromStringTestCase{"045", 2045},
+ SetExpirationYearFromStringTestCase{"9", 2009},
- // Unrecognized year values.
- SetExpirationYearFromStringTestCase{"052045", 0},
- SetExpirationYearFromStringTestCase{"123", 0},
- SetExpirationYearFromStringTestCase{"y2045", 0}));
+ // Unrecognized year values.
+ SetExpirationYearFromStringTestCase{"052045", 0},
+ SetExpirationYearFromStringTestCase{"123", 0},
+ SetExpirationYearFromStringTestCase{"y2045", 0}));
struct SetExpirationDateFromStringTestCase {
std::string expiration_date;
@@ -396,7 +397,7 @@ TEST_P(SetExpirationDateFromStringTest, SetExpirationDateFromString) {
EXPECT_EQ(test_case.expected_year, card.expiration_year());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
SetExpirationDateFromStringTest,
testing::Values(
@@ -486,7 +487,7 @@ TEST_P(IsLocalDuplicateOfServerCardTest, IsLocalDuplicateOfServerCard) {
<< " when comparing cards " << a.Label() << " and " << b.Label();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
IsLocalDuplicateOfServerCardTest,
testing::Values(
@@ -517,9 +518,6 @@ INSTANTIATE_TEST_CASE_P(
LOCAL_CARD, "", "423456789012", "", "", "1", MASKED_SERVER_CARD,
"John Dillinger", "9012", "01", "2010", "1", kVisaCard, true},
IsLocalDuplicateOfServerCardTestCase{
- LOCAL_CARD, "", "423456789012", "", "", "1", MASKED_SERVER_CARD,
- "John Dillinger", "9012", "01", "2010", "1", kMasterCard, false},
- IsLocalDuplicateOfServerCardTestCase{
LOCAL_CARD, "John Dillinger", "4234-5678-9012", "01", "2010", "1",
FULL_SERVER_CARD, "John Dillinger", "423456789012", "01", "2010",
"1", nullptr, true},
@@ -536,31 +534,123 @@ TEST(CreditCardTest, HasSameNumberAs) {
EXPECT_TRUE(a.HasSameNumberAs(b));
EXPECT_TRUE(b.HasSameNumberAs(a));
- // Same number.
+ // Cards with the same number are the same.
a.set_record_type(CreditCard::LOCAL_CARD);
a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
- a.set_record_type(CreditCard::LOCAL_CARD);
+ b.set_record_type(CreditCard::LOCAL_CARD);
b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
EXPECT_TRUE(a.HasSameNumberAs(b));
EXPECT_TRUE(b.HasSameNumberAs(a));
- // Local cards shouldn't match even if the last 4 are the same.
+ // Local cards with different overall numbers shouldn't match even if the last
+ // four digits are the same.
a.set_record_type(CreditCard::LOCAL_CARD);
a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
- a.set_record_type(CreditCard::LOCAL_CARD);
+ b.set_record_type(CreditCard::LOCAL_CARD);
b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111222222221111"));
EXPECT_FALSE(a.HasSameNumberAs(b));
EXPECT_FALSE(b.HasSameNumberAs(a));
- // Likewise if one is an unmasked server card.
+ // When one card is a full server card, the other is a local card, and the
+ // cards have different overall numbers but the same last four digits, they
+ // should not match.
a.set_record_type(CreditCard::FULL_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111222222221111"));
EXPECT_FALSE(a.HasSameNumberAs(b));
EXPECT_FALSE(b.HasSameNumberAs(a));
- // But if one is a masked card, then they should.
- b.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ // When one card is a masked server card, the other is a local card, and the
+ // cards have the same last four digits, they should match.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4331111111111111"));
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ EXPECT_TRUE(b.HasSameNumberAs(a));
+
+ // When one card is a masked server card, the other is a full server card, and
+ // the cards have the same last four digits, they should match.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.set_record_type(CreditCard::FULL_SERVER_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4331111111111111"));
EXPECT_TRUE(a.HasSameNumberAs(b));
EXPECT_TRUE(b.HasSameNumberAs(a));
+
+ // If one card is masked, then partial or missing expiration date information
+ // should not prevent the function from returning true.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
+ a.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2025"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16(""));
+ b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16(""));
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ EXPECT_TRUE(b.HasSameNumberAs(a));
+
+ // If one card is masked, then non-matching expiration months should cause the
+ // function to return false.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
+ a.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16(""));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("03"));
+ b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16(""));
+ EXPECT_FALSE(a.HasSameNumberAs(b));
+ EXPECT_FALSE(b.HasSameNumberAs(a));
+
+ // If one card is masked, then non-matching expiration years should cause the
+ // function to return false.
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16(""));
+ a.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2025"));
+ b.set_record_type(CreditCard::LOCAL_CARD);
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16(""));
+ b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2026"));
+ EXPECT_FALSE(a.HasSameNumberAs(b));
+ EXPECT_FALSE(b.HasSameNumberAs(a));
+}
+
+TEST(CreditCardTest, HasSameNumberAs_LogMaskedCardComparisonNetworksMatch) {
+ CreditCard a(base::GenerateGUID(), std::string());
+ CreditCard b(base::GenerateGUID(), std::string());
+
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetNetworkForMaskedCard(kVisaCard);
+ // CreditCard b's network is set to kVisaCard because it starts with 4, so the
+ // two cards have the same network.
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.MaskedCardComparisonNetworksMatch", true, 1);
+}
+
+TEST(CreditCardTest,
+ HasSameNumberAs_LogMaskedCardComparisonNetworksDoNotMatch) {
+ CreditCard a(base::GenerateGUID(), std::string());
+ CreditCard b(base::GenerateGUID(), std::string());
+
+ a.set_record_type(CreditCard::MASKED_SERVER_CARD);
+ a.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ a.SetNetworkForMaskedCard(kDiscoverCard);
+ // CreditCard b's network is set to kVisaCard because it starts with 4. The
+ // two cards have the same last four digits, but their networks are different,
+ // so this discrepancy should be logged.
+ b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
+ base::HistogramTester histogram_tester;
+ EXPECT_TRUE(a.HasSameNumberAs(b));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.MaskedCardComparisonNetworksMatch", false, 1);
}
TEST(CreditCardTest, Compare) {
@@ -931,9 +1021,9 @@ TEST(CreditCardTest, IsValidCardNumberAndExpiryDate) {
base::Time::Exploded now_exploded;
now.LocalExplode(&now_exploded);
card.SetRawInfo(CREDIT_CARD_EXP_MONTH,
- base::IntToString16(now_exploded.month));
+ base::NumberToString16(now_exploded.month));
card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
- base::IntToString16(now_exploded.year - 1));
+ base::NumberToString16(now_exploded.year - 1));
card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
EXPECT_FALSE(card.IsValid());
EXPECT_FALSE(card.HasValidExpirationDate());
@@ -1152,9 +1242,9 @@ const CreditCardMatchingTypesCase kCreditCardMatchingTypesTestCases[] = {
{"2021", "01", "2019", LOCAL_CARD, ServerFieldTypeSet()},
};
-INSTANTIATE_TEST_CASE_P(CreditCardTest,
- CreditCardMatchingTypesTest,
- testing::ValuesIn(kCreditCardMatchingTypesTestCases));
+INSTANTIATE_TEST_SUITE_P(CreditCardTest,
+ CreditCardMatchingTypesTest,
+ testing::ValuesIn(kCreditCardMatchingTypesTestCases));
struct GetCardNetworkTestCase {
const char* card_number;
@@ -1162,7 +1252,7 @@ struct GetCardNetworkTestCase {
bool is_valid;
};
-// We are doing batches here because INSTANTIATE_TEST_CASE_P has a
+// We are doing batches here because INSTANTIATE_TEST_SUITE_P has a
// 50 upper limit.
class GetCardNetworkTestBatch1
: public testing::TestWithParam<GetCardNetworkTestCase> {};
@@ -1175,7 +1265,7 @@ TEST_P(GetCardNetworkTestBatch1, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch1,
testing::Values(
@@ -1238,7 +1328,7 @@ TEST_P(GetCardNetworkTestBatch2, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch2,
testing::Values(
@@ -1291,7 +1381,7 @@ TEST_P(GetCardNetworkTestBatch3, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch3,
testing::Values(
@@ -1351,7 +1441,7 @@ TEST_P(GetCardNetworkTestBatch4, GetCardNetwork) {
EXPECT_EQ(test_case.is_valid, IsValidCreditCardNumber(card_number));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
GetCardNetworkTestBatch4,
testing::Values(
@@ -1482,7 +1572,7 @@ TEST_P(ShouldUpdateExpirationTest, ShouldUpdateExpiration) {
card.ShouldUpdateExpiration(testingTimes.now_));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardTest,
ShouldUpdateExpirationTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/field_filler.cc b/chromium/components/autofill/core/browser/field_filler.cc
index e1e56eb081d..736b6684b6a 100644
--- a/chromium/components/autofill/core/browser/field_filler.cc
+++ b/chromium/components/autofill/core/browser/field_filler.cc
@@ -624,6 +624,7 @@ bool FieldFiller::FillFormField(const AutofillField& field,
FormFieldData* field_data,
const base::string16& cvc) {
const AutofillType type = field.Type();
+
// Don't fill if autocomplete=off is set on |field| on desktop for non credit
// card related fields.
if (!base::FeatureList::IsEnabled(features::kAutofillAlwaysFillAddresses) &&
@@ -632,6 +633,9 @@ bool FieldFiller::FillFormField(const AutofillField& field,
return false;
}
+ if (data_model.ShouldSkipFillingOrSuggesting(type.GetStorableType()))
+ return false;
+
base::string16 value = data_model.GetInfo(type, app_locale_);
if (type.GetStorableType() == CREDIT_CARD_VERIFICATION_CODE)
value = cvc;
diff --git a/chromium/components/autofill/core/browser/field_filler_unittest.cc b/chromium/components/autofill/core/browser/field_filler_unittest.cc
index eb2f698627f..82728e71ec7 100644
--- a/chromium/components/autofill/core/browser/field_filler_unittest.cc
+++ b/chromium/components/autofill/core/browser/field_filler_unittest.cc
@@ -110,6 +110,29 @@ void TestFillingExpirationMonth(const std::vector<const char*>& values,
EXPECT_EQ(ASCIIToUTF16("Nov"), field.option_contents[content_index]);
}
+void TestFillingInvalidFields(const base::string16& state,
+ const base::string16& city) {
+ AutofillProfile profile = test::GetFullProfile();
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
+ AutofillProfile::SERVER);
+ profile.SetValidityState(ADDRESS_HOME_CITY, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+
+ AutofillField field_state;
+ field_state.set_heuristic_type(ADDRESS_HOME_STATE);
+ AutofillField field_city;
+ field_city.set_heuristic_type(ADDRESS_HOME_CITY);
+
+ FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
+ filler.FillFormField(field_state, profile, &field_state,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(state, field_state.value);
+
+ filler.FillFormField(field_city, profile, &field_city,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(city, field_city.value);
+}
+
struct CreditCardTestCase {
std::string card_number_;
size_t total_splits_;
@@ -388,6 +411,82 @@ TEST_F(AutofillFieldFillerTest, FillFormField_AutocompleteOff_CreditCardField) {
EXPECT_EQ(ASCIIToUTF16("4111111111111111"), field.value);
}
+// Verify that when the relevant feature is enabled, the invalid fields don't
+// get filled.
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_ServerClient) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/base::string16(),
+ /*city=*/base::string16());
+}
+
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_OnlyServer) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation},
+ /*disabled_features=*/{features::kAutofillProfileClientValidation});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/base::string16(),
+ /*city=*/ASCIIToUTF16("Elysium"));
+}
+
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_OnlyClient) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillProfileServerValidation});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/ASCIIToUTF16("CA"),
+ /*city=*/base::string16());
+}
+
+TEST_F(AutofillFieldFillerTest, FillFormField_NoValidity) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{},
+ /*disabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation});
+ // State's validity is set by server and city's validity by client.
+ TestFillingInvalidFields(/*state=*/ASCIIToUTF16("CA"),
+ /*city=*/ASCIIToUTF16("Elysium"));
+}
+
+// Tests that using only client side validation, if the country is empty, the
+// address fields will get filled regardless of their invalidity.
+TEST_F(AutofillFieldFillerTest, FillFormField_Validity_CountryEmpty) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillProfileServerValidation});
+ AutofillProfile profile = test::GetFullProfile();
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16(""));
+ profile.SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+ profile.SetValidityState(EMAIL_ADDRESS, AutofillProfile::INVALID,
+ AutofillProfile::CLIENT);
+
+ AutofillField field_state;
+ field_state.set_heuristic_type(ADDRESS_HOME_STATE);
+ AutofillField field_email;
+ field_email.set_heuristic_type(EMAIL_ADDRESS);
+
+ FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
+ // State is filled, because it's an address field.
+ filler.FillFormField(field_state, profile, &field_state,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(ASCIIToUTF16("CA"), field_state.value);
+
+ // Email is not filled, because it's not an address field, and it doesn't
+ // depend on the country.
+ filler.FillFormField(field_email, profile, &field_email,
+ /*cvc=*/base::string16());
+ EXPECT_EQ(ASCIIToUTF16(""), field_email.value);
+}
+
struct AutofillFieldFillerTestCase {
HtmlFieldType field_type;
size_t field_max_length;
@@ -413,7 +512,7 @@ TEST_P(PhoneNumberTest, FillPhoneNumber) {
EXPECT_EQ(ASCIIToUTF16(test_case.expected_value), field.value);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
PhoneNumberTest,
testing::Values(
@@ -463,7 +562,7 @@ TEST_P(ExpirationYearTest, FillExpirationYearInput) {
EXPECT_EQ(ASCIIToUTF16(test_case.expected_value), field.value);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
ExpirationYearTest,
testing::Values(
@@ -527,7 +626,7 @@ TEST_P(ExpirationDateTest, FillExpirationDateInput) {
EXPECT_EQ(response, test_case.expected_response);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
ExpirationDateTest,
testing::Values(
@@ -717,7 +816,7 @@ TEST_P(AutofillSelectWithStatesTest, FillSelectWithStates) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
AutofillSelectWithStatesTest,
testing::Values(
@@ -805,7 +904,7 @@ TEST_P(AutofillSelectWithExpirationMonthTest,
test_case.select_values.size());
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
AutofillSelectWithExpirationMonthTest,
testing::Values(
@@ -1291,7 +1390,7 @@ TEST_P(AutofillStateTextTest, FillStateText) {
EXPECT_EQ(ASCIIToUTF16(test_case.expected_value), field.value);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillFieldFillerTest,
AutofillStateTextTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/field_types.h b/chromium/components/autofill/core/browser/field_types.h
index fe6d8ab5c1c..c10fd8df61d 100644
--- a/chromium/components/autofill/core/browser/field_types.h
+++ b/chromium/components/autofill/core/browser/field_types.h
@@ -169,9 +169,12 @@ enum ServerFieldType {
// Search term fields are detected, but not filled.
SEARCH_TERM = 97,
+ // Price fields are detected, but not filled.
+ PRICE = 98,
+
// No new types can be added without a corresponding change to the Autofill
// server.
- MAX_VALID_FIELD_TYPE = 98,
+ MAX_VALID_FIELD_TYPE = 99,
};
// The list of all HTML autocomplete field type hints supported by Chrome.
diff --git a/chromium/components/autofill/core/browser/form_data_importer.cc b/chromium/components/autofill/core/browser/form_data_importer.cc
index 03b9216973a..15e57a10910 100644
--- a/chromium/components/autofill/core/browser/form_data_importer.cc
+++ b/chromium/components/autofill/core/browser/form_data_importer.cc
@@ -14,6 +14,7 @@
#include <set>
#include <utility>
+#include "base/bind.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -176,7 +177,7 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::NEW_CARD);
credit_card_save_manager_->AttemptToOfferCardUploadSave(
- submitted_form, *imported_credit_card,
+ submitted_form, has_non_focusable_field_, *imported_credit_card,
/*uploading_local_card=*/imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::LOCAL_CARD);
} else {
@@ -184,7 +185,7 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
DCHECK(imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::NEW_CARD);
credit_card_save_manager_->AttemptToOfferCardLocalSave(
- *imported_credit_card);
+ has_non_focusable_field_, *imported_credit_card);
}
}
@@ -442,7 +443,10 @@ bool FormDataImporter::ImportCreditCard(
// there is for local cards.
for (const CreditCard* card :
personal_data_manager_->GetServerCreditCards()) {
- if (candidate_credit_card.HasSameNumberAs(*card)) {
+ if ((card->record_type() == CreditCard::MASKED_SERVER_CARD &&
+ card->LastFourDigits() == candidate_credit_card.LastFourDigits()) ||
+ (card->record_type() == CreditCard::FULL_SERVER_CARD &&
+ candidate_credit_card.HasSameNumberAs(*card))) {
// Don't update card if the expiration date is missing
if (candidate_credit_card.expiration_month() == 0 ||
candidate_credit_card.expiration_year() == 0) {
@@ -504,6 +508,9 @@ CreditCard FormDataImporter::ExtractCreditCardFromForm(
if (field_type.group() != CREDIT_CARD)
continue;
+ if (!field->is_focusable)
+ has_non_focusable_field_ = true;
+
// If we've seen the same credit card field type twice in the same form,
// set |has_duplicate_field_type| to true.
ServerFieldType server_field_type = field_type.GetStorableType();
diff --git a/chromium/components/autofill/core/browser/form_data_importer.h b/chromium/components/autofill/core/browser/form_data_importer.h
index 0a11aeb00a4..a195d96cc86 100644
--- a/chromium/components/autofill/core/browser/form_data_importer.h
+++ b/chromium/components/autofill/core/browser/form_data_importer.h
@@ -120,6 +120,10 @@ class FormDataImporter {
CreditCard ExtractCreditCardFromForm(const FormStructure& form,
bool* hasDuplicateFieldType);
+ // Whether the form imported has non-focusable fields after user entered
+ // information into it.
+ bool has_non_focusable_field_ = false;
+
// The associated autofill client. Weak reference.
AutofillClient* client_;
@@ -145,6 +149,7 @@ class FormDataImporter {
friend class AutofillMergeTest;
friend class FormDataImporterTest;
friend class FormDataImporterTestBase;
+ friend class LocalCardMigrationBrowserTest;
friend class SaveCardBubbleViewsFullFormBrowserTest;
friend class SaveCardInfobarEGTestHelper;
FRIEND_TEST_ALL_PREFIXES(AutofillMergeTest, MergeProfiles);
diff --git a/chromium/components/autofill/core/browser/form_data_importer_unittest.cc b/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
index a205459df88..00280a55dde 100644
--- a/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -124,7 +124,6 @@ class FormDataImporterTestBase {
/*identity_manager=*/nullptr,
/*client_profile_validator=*/nullptr,
/*history_service=*/nullptr,
- /*cookie_manager_sevice=*/nullptr,
/*is_off_the_record=*/(user_mode == USER_MODE_INCOGNITO));
personal_data_manager_->AddObserver(&personal_data_observer_);
personal_data_manager_->OnSyncServiceInitialized(nullptr);
diff --git a/chromium/components/autofill/core/browser/form_field.cc b/chromium/components/autofill/core/browser/form_field.cc
index 3328e18c6f9..7b2aac8f7ab 100644
--- a/chromium/components/autofill/core/browser/form_field.cc
+++ b/chromium/components/autofill/core/browser/form_field.cc
@@ -23,7 +23,9 @@
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/name_field.h"
#include "components/autofill/core/browser/phone_field.h"
+#include "components/autofill/core/browser/price_field.h"
#include "components/autofill/core/browser/search_field.h"
+#include "components/autofill/core/browser/travel_field.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_regexes.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -31,14 +33,16 @@
namespace autofill {
// There's an implicit precedence determined by the values assigned here. Email
-// is currently the most important followed by Phone, Address, Credit Card,
-// Name, and Search.
+// is currently the most important followed by Phone, Travel, Address,
+// Credit Card, Name, and Search.
const float FormField::kBaseEmailParserScore = 1.4f;
const float FormField::kBasePhoneParserScore = 1.3f;
-const float FormField::kBaseAddressParserScore = 1.2f;
-const float FormField::kBaseCreditCardParserScore = 1.1f;
-const float FormField::kBaseNameParserScore = 1.0f;
-const float FormField::kBaseSearchParserScore = 0.9f;
+const float FormField::kBaseTravelParserScore = 1.2f;
+const float FormField::kBaseAddressParserScore = 1.1f;
+const float FormField::kBaseCreditCardParserScore = 1.0f;
+const float FormField::kBasePriceParserScore = 0.95f;
+const float FormField::kBaseNameParserScore = 0.9f;
+const float FormField::kBaseSearchParserScore = 0.8f;
// static
FieldCandidatesMap FormField::ParseFormFields(
@@ -69,6 +73,9 @@ FieldCandidatesMap FormField::ParseFormFields(
// Phone pass.
ParseFormFieldsPass(PhoneField::Parse, processed_fields, &field_candidates);
+ // Travel pass.
+ ParseFormFieldsPass(TravelField::Parse, processed_fields, &field_candidates);
+
// Address pass.
ParseFormFieldsPass(autofill::AddressField::Parse, processed_fields,
&field_candidates);
@@ -77,6 +84,9 @@ FieldCandidatesMap FormField::ParseFormFields(
ParseFormFieldsPass(CreditCardField::Parse, processed_fields,
&field_candidates);
+ // Price pass.
+ ParseFormFieldsPass(PriceField::Parse, processed_fields, &field_candidates);
+
// Name pass.
ParseFormFieldsPass(NameField::Parse, processed_fields, &field_candidates);
diff --git a/chromium/components/autofill/core/browser/form_field.h b/chromium/components/autofill/core/browser/form_field.h
index c14e88f2b98..8471b0ff3f6 100644
--- a/chromium/components/autofill/core/browser/form_field.h
+++ b/chromium/components/autofill/core/browser/form_field.h
@@ -60,8 +60,10 @@ class FormField {
// Initial values assigned to FieldCandidates by their corresponding parsers.
static const float kBaseEmailParserScore;
static const float kBasePhoneParserScore;
+ static const float kBaseTravelParserScore;
static const float kBaseAddressParserScore;
static const float kBaseCreditCardParserScore;
+ static const float kBasePriceParserScore;
static const float kBaseNameParserScore;
static const float kBaseSearchParserScore;
diff --git a/chromium/components/autofill/core/browser/form_structure.cc b/chromium/components/autofill/core/browser/form_structure.cc
index c715abb098f..07adcce22f2 100644
--- a/chromium/components/autofill/core/browser/form_structure.cc
+++ b/chromium/components/autofill/core/browser/form_structure.cc
@@ -18,7 +18,6 @@
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
-#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
diff --git a/chromium/components/autofill/core/browser/form_structure.h b/chromium/components/autofill/core/browser/form_structure.h
index 218c73ed169..414345d7744 100644
--- a/chromium/components/autofill/core/browser/form_structure.h
+++ b/chromium/components/autofill/core/browser/form_structure.h
@@ -319,7 +319,7 @@ class FormStructure {
// - Name for Autofill of first field
base::string16 GetIdentifierForRefill() const;
- int developer_engagement_metrics() { return developer_engagement_metrics_; };
+ int developer_engagement_metrics() { return developer_engagement_metrics_; }
void set_randomized_encoder(std::unique_ptr<RandomizedEncoder> encoder);
@@ -348,7 +348,7 @@ class FormStructure {
if (sectioned_indexes.empty())
return (size_t)-1; // Shouldn't happen.
return sectioned_indexes.back().back();
- };
+ }
void AddFieldIndex(const size_t index, bool is_new_section) {
if (is_new_section || Empty()) {
diff --git a/chromium/components/autofill/core/browser/label_formatter.cc b/chromium/components/autofill/core/browser/label_formatter.cc
new file mode 100644
index 00000000000..32426dd7790
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter.cc
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+
+LabelFormatter::LabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types)
+ : app_locale_(app_locale),
+ focused_field_type_(focused_field_type),
+ field_types_(field_types) {}
+LabelFormatter::~LabelFormatter() = default;
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter.h b/chromium/components/autofill/core/browser/label_formatter.h
new file mode 100644
index 00000000000..d436401044d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter.h
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+
+namespace autofill {
+
+// Handles the creation of Suggestions' disambiguating labels.
+class LabelFormatter {
+ public:
+ LabelFormatter(const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types);
+ virtual ~LabelFormatter();
+
+ // Returns a collection of |labels| formed by extracting useful disambiguating
+ // information from a collection of |profiles|.
+ virtual std::vector<base::string16> GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const = 0;
+
+ protected:
+ const std::string& app_locale() const { return app_locale_; }
+ ServerFieldType focused_field_type() const { return focused_field_type_; }
+ const std::vector<ServerFieldType>& field_types() const {
+ return field_types_;
+ }
+
+ private:
+ // The locale for which to generate labels. This reflects the language and
+ // country for which the application is translated, e.g. en_AU for Austalian
+ // English.
+ std::string app_locale_;
+
+ // The field on which the user is currently focused.
+ ServerFieldType focused_field_type_;
+
+ // A collection of meaningful field types in the form with which the user is
+ // interacting.
+ std::vector<ServerFieldType> field_types_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils.cc b/chromium/components/autofill/core/browser/label_formatter_utils.cc
new file mode 100644
index 00000000000..53d8eab8836
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter_utils.cc
@@ -0,0 +1,115 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
+#include <memory>
+#include <set>
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/address_form_label_formatter.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/contact_form_label_formatter.h"
+#include "components/autofill/core/browser/validation.h"
+
+namespace autofill {
+namespace {
+
+bool ContainsName(uint32_t groups) {
+ return groups & label_formatter_groups::kName;
+}
+
+bool ContainsAddress(uint32_t groups) {
+ return groups & label_formatter_groups::kAddress;
+}
+
+bool ContainsEmail(uint32_t groups) {
+ return groups & label_formatter_groups::kEmail;
+}
+
+bool ContainsPhone(uint32_t groups) {
+ return groups & label_formatter_groups::kPhone;
+}
+
+std::set<FieldTypeGroup> GetFieldTypeGroups(uint32_t groups) {
+ std::set<FieldTypeGroup> field_type_groups;
+ if (ContainsName(groups)) {
+ field_type_groups.insert(NAME);
+ }
+ if (ContainsAddress(groups)) {
+ field_type_groups.insert(ADDRESS_HOME);
+ }
+ if (ContainsEmail(groups)) {
+ field_type_groups.insert(EMAIL);
+ }
+ if (ContainsPhone(groups)) {
+ field_type_groups.insert(PHONE_HOME);
+ }
+ return field_type_groups;
+}
+
+} // namespace
+
+std::vector<ServerFieldType> FilterFieldTypes(
+ const std::vector<ServerFieldType>& field_types) {
+ std::vector<ServerFieldType> filtered_field_types;
+ for (const ServerFieldType& field_type : field_types) {
+ const FieldTypeGroup group =
+ AutofillType(AutofillType(field_type).GetStorableType()).group();
+ if (group == NAME || group == ADDRESS_HOME || group == EMAIL ||
+ group == PHONE_HOME) {
+ filtered_field_types.push_back(field_type);
+ }
+ }
+ return filtered_field_types;
+}
+
+uint32_t DetermineGroups(const std::vector<ServerFieldType>& field_types) {
+ uint32_t group_bitmask = 0;
+ for (const ServerFieldType& type : field_types) {
+ const FieldTypeGroup group =
+ AutofillType(AutofillType(type).GetStorableType()).group();
+ switch (group) {
+ case autofill::NAME:
+ group_bitmask |= label_formatter_groups::kName;
+ break;
+ case autofill::ADDRESS_HOME:
+ group_bitmask |= label_formatter_groups::kAddress;
+ break;
+ case autofill::EMAIL:
+ group_bitmask |= label_formatter_groups::kEmail;
+ break;
+ case autofill::PHONE_HOME:
+ group_bitmask |= label_formatter_groups::kPhone;
+ break;
+ default:
+ break;
+ }
+ }
+ return group_bitmask;
+}
+
+std::unique_ptr<LabelFormatter> Create(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types) {
+ const uint32_t groups = DetermineGroups(field_types);
+
+ if (!ContainsName(groups)) {
+ return nullptr;
+ }
+ if (ContainsAddress(groups) && !ContainsEmail(groups) &&
+ !ContainsPhone(groups)) {
+ return std::make_unique<AddressFormLabelFormatter>(
+ app_locale, focused_field_type, FilterFieldTypes(field_types));
+ }
+ if (ContainsEmail(groups) || ContainsPhone(groups)) {
+ return std::make_unique<ContactFormLabelFormatter>(
+ app_locale, focused_field_type, FilterFieldTypes(field_types),
+ GetFieldTypeGroups(groups));
+ }
+ return nullptr;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils.h b/chromium/components/autofill/core/browser/label_formatter_utils.h
new file mode 100644
index 00000000000..80b21942c39
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter_utils.h
@@ -0,0 +1,58 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_UTILS_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_UTILS_H_
+
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter.h"
+
+namespace autofill {
+namespace label_formatter_groups {
+
+// Bits for FieldTypeGroup options.
+// The form contains at least one field associated with the NAME_HOME or
+// NAME_BILLING FieldTypeGroups.
+constexpr uint32_t kName = 1 << 0;
+// The form contains at least one field associated with the ADDRESS_HOME or
+// ADDRESS_BILLING FieldTypeGroups.
+constexpr uint32_t kAddress = 1 << 1;
+// The form contains at least one field associated with the EMAIL
+// FieldTypeGroup.
+constexpr uint32_t kEmail = 1 << 2;
+// The form contains at least one field associated with the PHONE_HOME or
+// PHONE_BILLING FieldTypeGroup.
+constexpr uint32_t kPhone = 1 << 3;
+
+} // namespace label_formatter_groups
+
+// Returns a subset of meaningful ServerFieldTypes found in |field_types|.
+// ServerFieldTypes like NO_SERVER_DATA and UNKNOWN_TYPE are frequently found in
+// the collection of types sent from the frontend. Other types, e.g.
+// COMPANY_NAME and PHONE_FAX_WHOLE_NUMBER, are also sometimes present. These
+// types are not useful to LabelFormatters, so only types related to names,
+// addresses, emails, and phone numbers are in the results.
+std::vector<ServerFieldType> FilterFieldTypes(
+ const std::vector<ServerFieldType>& field_types);
+
+// Returns a bitmask indicating whether the NAME, ADDRESS_HOME, EMAIL, and
+// PHONE_HOME FieldTypeGroups are associated with the given |field_types|.
+uint32_t DetermineGroups(const std::vector<ServerFieldType>& field_types);
+
+// Creates a form-specific LabelFormatter according to |field_types|. If the
+// given |field_types| do not correspond to a LabelFormatter, then nullptr will
+// be returned.
+std::unique_ptr<LabelFormatter> Create(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types);
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_UTILS_H_
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc b/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc
new file mode 100644
index 00000000000..660cb0263d3
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc
@@ -0,0 +1,100 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+namespace {
+using label_formatter_groups::kAddress;
+using label_formatter_groups::kEmail;
+using label_formatter_groups::kName;
+using label_formatter_groups::kPhone;
+
+} // namespace
+
+TEST(LabelFormatterUtilsTest, FilterFieldTypesNoFiltering) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_LAST, NAME_BILLING_LAST, ADDRESS_HOME_ZIP,
+ ADDRESS_BILLING_ZIP, EMAIL_ADDRESS, PHONE_HOME_NUMBER,
+ PHONE_BILLING_NUMBER};
+ const std::vector<ServerFieldType> filtered_field_types =
+ FilterFieldTypes(field_types);
+ EXPECT_EQ(field_types, filtered_field_types);
+}
+
+TEST(LabelFormatterUtilsTest, FilterFieldTypesFilterCompany) {
+ const std::vector<ServerFieldType> field_types{NAME_LAST, COMPANY_NAME};
+ const std::vector<ServerFieldType> expected_filtered_field_types{NAME_LAST};
+ const std::vector<ServerFieldType> filtered_field_types =
+ FilterFieldTypes(field_types);
+ EXPECT_EQ(expected_filtered_field_types, filtered_field_types);
+}
+
+TEST(LabelFormatterUtilsTest, FilterFieldTypesForNoGivenFieldTypes) {
+ const std::vector<ServerFieldType> field_types =
+ std::vector<ServerFieldType>();
+ const std::vector<ServerFieldType> filtered_field_types =
+ FilterFieldTypes(field_types);
+ EXPECT_EQ(field_types, filtered_field_types);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForHomeNameAndAddress) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_FIRST, NAME_LAST, ADDRESS_HOME_LINE1,
+ ADDRESS_HOME_CITY, ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP};
+
+ const uint32_t expected_group_bitmask = kName | kAddress;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForBillingNameAndAddress) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_BILLING_FULL, ADDRESS_BILLING_LINE1, ADDRESS_BILLING_CITY,
+ ADDRESS_BILLING_STATE, ADDRESS_BILLING_ZIP};
+
+ const uint32_t expected_group_bitmask = kName | kAddress;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForHomeNamePhoneAndEmail) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_FULL, PHONE_HOME_CITY_AND_NUMBER, EMAIL_ADDRESS};
+
+ const uint32_t expected_group_bitmask = kName | kPhone | kEmail;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForBillingNamePhoneAndEmail) {
+ const std::vector<ServerFieldType> field_types{
+ NAME_BILLING_FULL, PHONE_BILLING_WHOLE_NUMBER, EMAIL_ADDRESS};
+
+ const uint32_t expected_group_bitmask = kName | kPhone | kEmail;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForUnknownServerFieldType) {
+ const std::vector<ServerFieldType> field_types{UNKNOWN_TYPE, NAME_FULL,
+ ADDRESS_HOME_ZIP};
+
+ const uint32_t expected_group_bitmask = kName | kAddress;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+TEST(LabelFormatterUtilsTest, DetermineGroupsForNoServerFieldTypes) {
+ const std::vector<ServerFieldType> field_types =
+ std::vector<ServerFieldType>();
+ const uint32_t expected_group_bitmask = 0;
+ const uint32_t group_bitmask = DetermineGroups(field_types);
+ EXPECT_EQ(expected_group_bitmask, group_bitmask);
+}
+
+} // namespace autofill \ No newline at end of file
diff --git a/chromium/components/autofill/core/browser/legacy_strike_database.cc b/chromium/components/autofill/core/browser/legacy_strike_database.cc
index e6fbef3f7d3..d575b2e43ae 100644
--- a/chromium/components/autofill/core/browser/legacy_strike_database.cc
+++ b/chromium/components/autofill/core/browser/legacy_strike_database.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
diff --git a/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc b/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc
index af63074c357..44e60a4ae0c 100644
--- a/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc
+++ b/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
diff --git a/chromium/components/autofill/core/browser/legal_message_line_unittest.cc b/chromium/components/autofill/core/browser/legal_message_line_unittest.cc
index e3147f1ee7d..6a5c5ba8fd8 100644
--- a/chromium/components/autofill/core/browser/legal_message_line_unittest.cc
+++ b/chromium/components/autofill/core/browser/legal_message_line_unittest.cc
@@ -104,7 +104,7 @@ class LegalMessageLineTest : public ::testing::TestWithParam<TestCase> {
// Verifies that legal message parsing is correct.
TEST_P(LegalMessageLineTest, Parsing) {
std::unique_ptr<base::Value> value(
- base::JSONReader::Read(GetParam().message_json));
+ base::JSONReader::ReadDeprecated(GetParam().message_json));
ASSERT_TRUE(value);
base::DictionaryValue* dictionary = nullptr;
EXPECT_TRUE(value->GetAsDictionary(&dictionary));
@@ -114,9 +114,9 @@ TEST_P(LegalMessageLineTest, Parsing) {
GetParam().escape_apostrophes);
EXPECT_EQ(GetParam().expected_lines, actual_lines);
-};
+}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
TestCases,
LegalMessageLineTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager.cc b/chromium/components/autofill/core/browser/local_card_migration_manager.cc
index 764f9159b7f..f77d16d7bde 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager.cc
+++ b/chromium/components/autofill/core/browser/local_card_migration_manager.cc
@@ -10,6 +10,8 @@
#include <vector>
#include "base/bind.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_experiments.h"
@@ -39,7 +41,19 @@ LocalCardMigrationManager::LocalCardMigrationManager(
payments_client_(payments_client),
app_locale_(app_locale),
personal_data_manager_(personal_data_manager),
- weak_ptr_factory_(this) {}
+ weak_ptr_factory_(this) {
+ // This is to initialize StrikeDatabase is if it hasn't been already, so that
+ // its cache would be loaded and ready to use when the first LCMM is created.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillSaveCreditCardUsesStrikeSystemV2) ||
+ base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
+ // Only init when |kAutofillSaveCreditCardUsesStrikeSystemV2| is enabled. If
+ // flag is off and LegacyStrikeDatabase instead of StrikeDatabase is used,
+ // this init will cause failure on GetStrikes().
+ client_->GetStrikeDatabase();
+ }
+}
LocalCardMigrationManager::~LocalCardMigrationManager() {}
@@ -62,9 +76,26 @@ bool LocalCardMigrationManager::ShouldOfferLocalCardMigration(
if (!IsCreditCardMigrationEnabled())
return false;
- // Don't show the the prompt if user cancelled/rejected previously.
- if (prefs::IsLocalCardMigrationPromptPreviouslyCancelled(client_->GetPrefs()))
+ // Don't show the prompt if max strike count was reached.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2) &&
+ GetLocalCardMigrationStrikeDatabase()->IsMaxStrikesLimitReached()) {
+ switch (imported_credit_card_record_type) {
+ case FormDataImporter::ImportedCreditCardRecordType::LOCAL_CARD:
+ AutofillMetrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ AutofillMetrics::SaveTypeMetric::LOCAL);
+ break;
+ case FormDataImporter::ImportedCreditCardRecordType::SERVER_CARD:
+ AutofillMetrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
+ AutofillMetrics::SaveTypeMetric::SERVER);
+ break;
+ }
+ return false;
+ } else if (prefs::IsLocalCardMigrationPromptPreviouslyCancelled(
+ client_->GetPrefs())) {
+ // Don't show the the prompt if user cancelled/rejected previously.
return false;
+ }
// Fetch all migratable credit cards and store in |migratable_credit_cards_|.
GetMigratableCreditCards();
@@ -88,6 +119,9 @@ void LocalCardMigrationManager::AttemptToOfferLocalCardMigration(
return;
migration_request_ = payments::PaymentsClient::MigrationRequestDetails();
+ if (observer_for_testing_)
+ observer_for_testing_->OnDecideToRequestLocalCardMigration();
+
payments_client_->GetUploadDetails(
std::vector<AutofillProfile>(), GetDetectedValues(),
/*active_experiments=*/std::vector<const char*>(), app_locale_,
@@ -116,16 +150,32 @@ void LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog(
user_accepted_main_migration_dialog_ = true;
AutofillMetrics::LogLocalCardMigrationPromptMetric(
local_card_migration_origin_, AutofillMetrics::MAIN_DIALOG_ACCEPTED);
+
+ // Log number of LocalCardMigration strikes when migration was accepted.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
+ base::UmaHistogramCounts1000(
+ "Autofill.StrikeDatabase.StrikesPresentWhenLocalCardMigrationAccepted",
+ GetLocalCardMigrationStrikeDatabase()->GetStrikes());
+ }
+
+ // If there are cards which aren't selected, add 3 strikes to
+ // LocalCardMigrationStrikeDatabase.
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2) &&
+ (selected_card_guids.size() < migratable_credit_cards_.size())) {
+ GetLocalCardMigrationStrikeDatabase()->AddStrikes(
+ LocalCardMigrationStrikeDatabase::
+ kStrikesToAddWhenCardsDeselectedAtMigration);
+ }
+
// Update the |migratable_credit_cards_| with the |selected_card_guids|. This
// will remove any card from |migratable_credit_cards_| of which the GUID is
// not in |selected_card_guids|.
auto card_is_selected = [&selected_card_guids](MigratableCreditCard& card) {
return !base::ContainsValue(selected_card_guids, card.credit_card().guid());
};
- migratable_credit_cards_.erase(
- std::remove_if(migratable_credit_cards_.begin(),
- migratable_credit_cards_.end(), card_is_selected),
- migratable_credit_cards_.end());
+ base::EraseIf(migratable_credit_cards_, card_is_selected);
// Populating risk data and offering migration two-round pop-ups occur
// asynchronously. If |migration_risk_data_| has already been loaded, send the
// migrate local cards request. Otherwise, continue to wait and let
@@ -145,24 +195,44 @@ bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() {
bool migration_experiment_enabled =
features::GetLocalCardMigrationExperimentalFlag() !=
features::LocalCardMigrationExperimentalFlag::kMigrationDisabled;
- bool credit_card_upload_enabled = ::autofill::IsCreditCardUploadEnabled(
- client_->GetPrefs(), client_->GetSyncService(),
- client_->GetIdentityManager()->GetPrimaryAccountInfo().email);
+
+ // If |observer_for_testing_| is set, assume we are in a browsertest and
+ // credit card upload should be enabled by default. Cannot get around this as
+ // Chrome OS testing requires an unsupported email domain (i.e.
+ // stub-user@example.com).
+ bool credit_card_upload_enabled =
+ observer_for_testing_ ||
+ ::autofill::IsCreditCardUploadEnabled(
+ client_->GetPrefs(), client_->GetSyncService(),
+ personal_data_manager_->GetAccountInfoForPaymentsServer().email);
+
bool has_google_payments_account =
(payments::GetBillingCustomerId(personal_data_manager_,
payments_client_->GetPrefService()) != 0);
- bool sync_feature_enabled =
- (personal_data_manager_->GetSyncSigninState() ==
- AutofillSyncSigninState::kSignedInAndSyncFeature);
+
+ AutofillSyncSigninState sync_state =
+ personal_data_manager_->GetSyncSigninState();
+
return migration_experiment_enabled && credit_card_upload_enabled &&
- has_google_payments_account && sync_feature_enabled;
+ has_google_payments_account &&
+ // User signed-in and turned sync on.
+ (sync_state == AutofillSyncSigninState::kSignedInAndSyncFeature ||
+ // User signed-in but not turned on sync.
+ (sync_state == AutofillSyncSigninState::
+ kSignedInAndWalletSyncTransportEnabled &&
+ base::FeatureList::IsEnabled(
+ features::kAutofillEnableLocalCardMigrationForNonSyncUser)));
}
void LocalCardMigrationManager::OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
+ if (observer_for_testing_)
+ observer_for_testing_->OnReceivedGetUploadDetailsResponse();
+
if (result == AutofillClient::SUCCESS) {
migration_request_.context_token = context_token;
legal_message_ = base::DictionaryValue::From(std::move(legal_message));
@@ -196,6 +266,9 @@ void LocalCardMigrationManager::OnDidMigrateLocalCards(
AutofillClient::PaymentsRpcResult result,
std::unique_ptr<std::unordered_map<std::string, std::string>> save_result,
const std::string& display_text) {
+ if (observer_for_testing_)
+ observer_for_testing_->OnReceivedMigrateCardsResponse();
+
if (!save_result)
return;
@@ -203,26 +276,32 @@ void LocalCardMigrationManager::OnDidMigrateLocalCards(
std::vector<CreditCard> migrated_cards;
// Traverse the migratable credit cards to update each migrated card status.
for (MigratableCreditCard& card : migratable_credit_cards_) {
+ // If it is run in a test, count all cards as successfully migrated.
+ if (observer_for_testing_) {
+ migrated_cards.push_back(card.credit_card());
+ continue;
+ }
+
// Not every card exists in the |save_result| since some cards are
// unchecked by the user and not migrated.
auto it = save_result->find(card.credit_card().guid());
- // If current card exists in the |save_result|, update its migration
- // status.
- if (it != save_result->end()) {
- // Server-side response can return SUCCESS, TEMPORARY_FAILURE, or
- // PERMANENT_FAILURE (see SaveResult enum). Branch here depending on
- // which is received.
- if (it->second == kMigrationResultPermanentFailure ||
- it->second == kMigrationResultTemporaryFailure) {
- card.set_migration_status(autofill::MigratableCreditCard::
- MigrationStatus::FAILURE_ON_UPLOAD);
- } else if (it->second == kMigrationResultSuccess) {
- card.set_migration_status(autofill::MigratableCreditCard::
- MigrationStatus::SUCCESS_ON_UPLOAD);
- migrated_cards.push_back(card.credit_card());
- } else {
- NOTREACHED();
- }
+ // If current card does not exist in the |save_result|, skip it.
+ if (it == save_result->end())
+ continue;
+
+ // Otherwise update its migration status. Server-side response can return
+ // SUCCESS, TEMPORARY_FAILURE, or PERMANENT_FAILURE (see SaveResult
+ // enum). Branch here depending on which is received.
+ if (it->second == kMigrationResultPermanentFailure ||
+ it->second == kMigrationResultTemporaryFailure) {
+ card.set_migration_status(
+ autofill::MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD);
+ } else if (it->second == kMigrationResultSuccess) {
+ card.set_migration_status(
+ autofill::MigratableCreditCard::MigrationStatus::SUCCESS_ON_UPLOAD);
+ migrated_cards.push_back(card.credit_card());
+ } else {
+ NOTREACHED();
}
}
// Remove cards that were successfully migrated from local storage.
@@ -254,6 +333,9 @@ void LocalCardMigrationManager::OnDidGetMigrationRiskData(
// Send the migration request. Will call payments_client to create a new
// PaymentsRequest. Also create a new callback function OnDidMigrateLocalCards.
void LocalCardMigrationManager::SendMigrateLocalCardsRequest() {
+ if (observer_for_testing_)
+ observer_for_testing_->OnSentMigrateCardsRequest();
+
migration_request_.app_locale = app_locale_;
migration_request_.billing_customer_number = payments::GetBillingCustomerId(
personal_data_manager_, payments_client_->GetPrefService());
@@ -264,6 +346,16 @@ void LocalCardMigrationManager::SendMigrateLocalCardsRequest() {
user_accepted_main_migration_dialog_ = false;
}
+LocalCardMigrationStrikeDatabase*
+LocalCardMigrationManager::GetLocalCardMigrationStrikeDatabase() {
+ if (local_card_migration_strike_database_.get() == nullptr) {
+ local_card_migration_strike_database_ =
+ std::make_unique<LocalCardMigrationStrikeDatabase>(
+ LocalCardMigrationStrikeDatabase(client_->GetStrikeDatabase()));
+ }
+ return local_card_migration_strike_database_.get();
+}
+
// Pops up a larger, modal dialog showing the local cards to be uploaded. Pass
// the reference of vector<MigratableCreditCard> and the callback function is
// OnUserAcceptedMainMigrationDialog(). Can be called when user agrees to
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager.h b/chromium/components/autofill/core/browser/local_card_migration_manager.h
index 06e5ce5832c..02365d324a1 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager.h
+++ b/chromium/components/autofill/core/browser/local_card_migration_manager.h
@@ -7,11 +7,13 @@
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/local_card_migration_strike_database.h"
#include "components/autofill/core/browser/payments/payments_client.h"
namespace autofill {
@@ -43,7 +45,7 @@ class MigratableCreditCard {
FAILURE_ON_UPLOAD,
};
- MigratableCreditCard(const CreditCard& credit_card);
+ explicit MigratableCreditCard(const CreditCard& credit_card);
~MigratableCreditCard();
CreditCard credit_card() const { return credit_card_; }
@@ -66,6 +68,16 @@ class MigratableCreditCard {
// Owned by FormDataImporter.
class LocalCardMigrationManager {
public:
+ // An observer class used by browsertests that gets notified whenever
+ // particular actions occur.
+ class ObserverForTest {
+ public:
+ virtual void OnDecideToRequestLocalCardMigration() = 0;
+ virtual void OnReceivedGetUploadDetailsResponse() = 0;
+ virtual void OnSentMigrateCardsRequest() = 0;
+ virtual void OnReceivedMigrateCardsResponse() = 0;
+ };
+
// The parameters should outlive the LocalCardMigrationManager.
LocalCardMigrationManager(AutofillClient* client,
payments::PaymentsClient* payments_client,
@@ -123,7 +135,8 @@ class LocalCardMigrationManager {
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message);
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges);
// Callback after successfully getting the migration save results. Map
// migration save result to each card depending on the |save_result|. Will
@@ -141,6 +154,7 @@ class LocalCardMigrationManager {
payments::PaymentsClient* payments_client_;
private:
+ friend class LocalCardMigrationBrowserTest;
FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest,
MigrateCreditCard_MigrationPermanentFailure);
FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest,
@@ -150,6 +164,9 @@ class LocalCardMigrationManager {
FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest,
MigrateCreditCard_ToggleIsChosen);
+ // Returns the LocalCardMigrationStrikeDatabase for |client_|.
+ LocalCardMigrationStrikeDatabase* GetLocalCardMigrationStrikeDatabase();
+
// Pops up a larger, modal dialog showing the local cards to be uploaded.
void ShowMainMigrationDialog();
@@ -161,6 +178,11 @@ class LocalCardMigrationManager {
// Finalizes the migration request and calls PaymentsClient.
void SendMigrateLocalCardsRequest();
+ // For testing.
+ void SetEventObserverForTesting(ObserverForTest* observer) {
+ observer_for_testing_ = observer;
+ }
+
std::unique_ptr<base::DictionaryValue> legal_message_;
std::string app_locale_;
@@ -187,6 +209,12 @@ class LocalCardMigrationManager {
// Record the triggering source of the local card migration.
AutofillMetrics::LocalCardMigrationOrigin local_card_migration_origin_;
+ // Initialized only during tests.
+ ObserverForTest* observer_for_testing_ = nullptr;
+
+ std::unique_ptr<LocalCardMigrationStrikeDatabase>
+ local_card_migration_strike_database_;
+
base::WeakPtrFactory<LocalCardMigrationManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(LocalCardMigrationManager);
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc b/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc
index 6dd9308c48a..9e6e3a98e10 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc
@@ -29,6 +29,7 @@
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/sync_utils.h"
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
@@ -81,6 +82,10 @@ class LocalCardMigrationManagerTest : public testing::Test {
local_card_migration_manager_ = new TestLocalCardMigrationManager(
autofill_driver_.get(), &autofill_client_, payments_client_,
&personal_data_);
+ std::unique_ptr<TestStrikeDatabase> test_strike_database =
+ std::make_unique<TestStrikeDatabase>();
+ strike_database_ = test_strike_database.get();
+ autofill_client_.set_test_strike_database(std::move(test_strike_database));
autofill::TestFormDataImporter* test_form_data_importer =
new TestFormDataImporter(
&autofill_client_, payments_client_,
@@ -108,16 +113,6 @@ class LocalCardMigrationManagerTest : public testing::Test {
request_context_ = nullptr;
}
- void EnableAutofillCreditCardLocalCardMigrationExperiment() {
- scoped_feature_list_.InitAndEnableFeature(
- features::kAutofillCreditCardLocalCardMigration);
- }
-
- void DisableAutofillCreditCardLocalCardMigrationExperiment() {
- scoped_feature_list_.InitAndDisableFeature(
- features::kAutofillCreditCardLocalCardMigration);
- }
-
void FormsSeen(const std::vector<FormData>& forms) {
autofill_manager_->OnFormsSeen(forms, base::TimeTicks());
}
@@ -177,6 +172,8 @@ class LocalCardMigrationManagerTest : public testing::Test {
MockAutocompleteHistoryManager autocomplete_history_manager_;
syncer::TestSyncService sync_service_;
base::test::ScopedFeatureList scoped_feature_list_;
+ // Ends up getting owned (and destroyed) by TestAutofillClient:
+ TestStrikeDatabase* strike_database_;
// Ends up getting owned (and destroyed) by TestFormDataImporter:
TestCreditCardSaveManager* credit_card_save_manager_;
// Ends up getting owned (and destroyed) by TestFormDataImporter:
@@ -188,7 +185,8 @@ class LocalCardMigrationManagerTest : public testing::Test {
// Having one local card on file and using it will not trigger migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseLocalCardWithOneLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -221,7 +219,8 @@ TEST_F(LocalCardMigrationManagerTest,
// trigger migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseNewCardWithAnyLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -251,7 +250,8 @@ TEST_F(LocalCardMigrationManagerTest,
// migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseLocalCardWithMoreLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -297,7 +297,8 @@ TEST_F(LocalCardMigrationManagerTest,
// cards as long as the other local cards are not eligible for migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseLocalCardWithInvalidLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -330,7 +331,8 @@ TEST_F(LocalCardMigrationManagerTest,
// will trigger migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseServerCardWithOneValidLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -379,7 +381,8 @@ TEST_F(LocalCardMigrationManagerTest,
// cards as long as the other local cards are not eligible for migration.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_UseServerCardWithNoneValidLocal) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -421,7 +424,8 @@ TEST_F(LocalCardMigrationManagerTest,
// is off, will not trigger migration.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_FeatureNotEnabled) {
// Turn off the experiment flag.
- DisableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndDisableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -448,20 +452,22 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_FeatureNotEnabled) {
}
// Do not trigger migration if user only signs in.
-TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnly) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnlyWhenExpOff) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillEnableAccountWalletStorage},
+ // Disabled
+ {features::kAutofillEnableLocalCardMigrationForNonSyncUser});
- // Make a non-primary account available with both a refresh token and cookie
- // to be in Sync Transport for Wallet mode, in which case this account is
- // signed in only without sync enabled.
- sync_service_.SetIsAuthenticatedAccountPrimary(false);
- sync_service_.SetActiveDataTypes(
- syncer::ModelTypeSet(syncer::AUTOFILL_WALLET_DATA));
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitWithFeatures(
- /*enabled_features=*/{features::kAutofillEnableAccountWalletStorage},
- /*disabled_features=*/{});
+ // Mock Chrome Sync is disabled.
+ local_card_migration_manager_->ResetSyncState(
+ AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled);
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
@@ -483,10 +489,50 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnly) {
EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
}
+// Trigger migration if user only signs in and if experiment is enabled.
+TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnlyWhenExpOn) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillEnableLocalCardMigrationForNonSyncUser,
+ features::kAutofillEnableAccountWalletStorage},
+ // Disabled
+ {});
+
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+
+ // Mock Chrome Sync is disabled.
+ local_card_migration_manager_->ResetSyncState(
+ AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled);
+
+ // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
+ // enter below.
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ // Add another local credit card.
+ AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+ test::NextYear().c_str(), "1", "guid2");
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ test::CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ // Edit the data, and submit.
+ EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "123");
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
+}
+
// Use one local card with more valid local cards available but billing customer
// number is blank, will not trigger migration.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_NoPaymentsAccount) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
@@ -512,7 +558,8 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_NoPaymentsAccount) {
// migratable.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_LocalCardMatchMaskedServerCard) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -549,7 +596,8 @@ TEST_F(LocalCardMigrationManagerTest,
// migratable.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_LocalCardMatchFullServerCard) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -581,7 +629,8 @@ TEST_F(LocalCardMigrationManagerTest,
// GetDetectedValues() should includes cardholder name if all cards have it.
TEST_F(LocalCardMigrationManagerTest, GetDetectedValues_AllWithCardHolderName) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -613,7 +662,8 @@ TEST_F(LocalCardMigrationManagerTest, GetDetectedValues_AllWithCardHolderName) {
// a cardholder name.
TEST_F(LocalCardMigrationManagerTest,
GetDetectedValues_OneCardWithoutCardHolderName) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -644,7 +694,8 @@ TEST_F(LocalCardMigrationManagerTest,
// account.
TEST_F(LocalCardMigrationManagerTest,
GetDetectedValues_IncludeGooglePaymentsAccount) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -675,7 +726,8 @@ TEST_F(LocalCardMigrationManagerTest,
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_ShouldAddMigrateCardsBillableServiceNumberInRequest) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -708,7 +760,8 @@ TEST_F(LocalCardMigrationManagerTest,
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_ShouldAddUploadCardSourceInRequest_CheckoutFlow) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -741,7 +794,8 @@ TEST_F(LocalCardMigrationManagerTest,
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_ShouldAddUploadCardSourceInRequest_SettingsPage) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -770,7 +824,8 @@ TEST_F(LocalCardMigrationManagerTest,
// be triggered.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_TriggerFromSettingsPage) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -809,7 +864,8 @@ TEST_F(LocalCardMigrationManagerTest,
// prompt are both triggered.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_TriggerFromSubmittedForm) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -840,7 +896,8 @@ TEST_F(LocalCardMigrationManagerTest,
// prompt are not triggered as user previously rejected the prompt.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_DontTriggerFromSubmittedForm) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -877,7 +934,8 @@ TEST_F(LocalCardMigrationManagerTest,
// Verify that given the parsed response from the payments client, the migration
// status is correctly set.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_MigrationSuccess) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -918,7 +976,8 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_MigrationSuccess) {
// status is correctly set.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_MigrationTemporaryFailure) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -961,7 +1020,8 @@ TEST_F(LocalCardMigrationManagerTest,
// status is correctly set.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_MigrationPermanentFailure) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
@@ -1002,7 +1062,8 @@ TEST_F(LocalCardMigrationManagerTest,
// Verify selected cards are correctly passed to manager.
TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_ToggleIsChosen) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1", "guid1");
AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
@@ -1025,7 +1086,8 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_ToggleIsChosen) {
}
TEST_F(LocalCardMigrationManagerTest, DeleteLocalCardViaMigrationDialog) {
- EnableAutofillCreditCardLocalCardMigrationExperiment();
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAutofillCreditCardLocalCardMigration);
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1", "guid1");
@@ -1038,4 +1100,175 @@ TEST_F(LocalCardMigrationManagerTest, DeleteLocalCardViaMigrationDialog) {
EXPECT_FALSE(personal_data_.GetCreditCardWithGUID("guid1"));
}
+// Use one local card with more valid local cards available, don't show prompt
+// if max strikes reached.
+TEST_F(LocalCardMigrationManagerTest,
+ MigrateLocalCreditCard_MaxStrikesReached) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ local_card_migration_strike_database.AddStrikes(7);
+
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 7);
+
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+ // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
+ // enter below.
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ // Add another local credit card, so it will trigger migration.
+ AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+ test::NextYear().c_str(), "1", "guid2");
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ test::CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ base::HistogramTester histogram_tester;
+ // Edit the data, and submit.
+ EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "123");
+ FormSubmitted(credit_card_form);
+
+ // Local card migration not triggered since max strikes have been reached.
+ EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
+
+ // Verify that the correct histogram entry was logged.
+ histogram_tester.ExpectBucketCount(
+ "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes",
+ AutofillMetrics::SaveTypeMetric::LOCAL, 1);
+}
+
+// Use one server card with more valid local cards available, don't show prompt
+// if max strikes reached.
+TEST_F(LocalCardMigrationManagerTest,
+ MigrateServerCreditCard_MaxStrikesReached) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ local_card_migration_strike_database.AddStrikes(7);
+
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 7);
+
+ // Set the billing_customer_number Priority Preference to designate
+ // existence of a Payments account.
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+
+ // Add a masked server credit card whose |TypeAndLastFourDigits| matches what
+ // we will enter below.
+ CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
+ test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
+ test::NextYear().c_str(), "1");
+ credit_card.SetNetworkForMaskedCard(kVisaCard);
+ personal_data_.AddServerCreditCard(credit_card);
+ // Add one valid local credit card, so it will trigger migration
+ AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+ test::NextYear().c_str(), "1", "guid1");
+
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ test::CreateTestCreditCardFormData(&credit_card_form, true, false);
+ FormsSeen(std::vector<FormData>(1, credit_card_form));
+
+ base::HistogramTester histogram_tester;
+ // Edit the data, and submit.
+ EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "123");
+ FormSubmitted(credit_card_form);
+
+ // Local card migration not triggered since max strikes have been reached.
+ EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered());
+
+ // Verify that the correct histogram entry was logged.
+ histogram_tester.ExpectBucketCount(
+ "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes",
+ AutofillMetrics::SaveTypeMetric::SERVER, 1);
+}
+
+// When local card migration is attempted and some cards aren't selected,
+// 3 strikes should be added.
+TEST_F(LocalCardMigrationManagerTest,
+ MigrateCreditCard_StrikesAddedWhenSomeCardsNotSelected) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ // LocalCardMigrationStrikeDatabase should initially have no strikes.
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 0);
+
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
+ test::NextYear().c_str(), "1", "guid2");
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+ local_card_migration_manager_->GetMigratableCreditCards();
+
+ // Only select one of the two cards.
+ autofill_client_.set_migration_card_selections(
+ std::vector<std::string>{"guid1"});
+ local_card_migration_manager_->AttemptToOfferLocalCardMigration(true);
+
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3);
+}
+
+// When local card migration is accepted, UMA metrics for LocalCardMigration
+// strike count is logged.
+TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_StrikeCountUMALogged) {
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled
+ {features::kAutofillCreditCardLocalCardMigration,
+ features::kAutofillLocalCardMigrationUsesStrikeSystemV2},
+ // Disabled
+ {});
+
+ AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+ test::NextYear().c_str(), "1", "guid1");
+ AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
+ test::NextYear().c_str(), "1", "guid2");
+ autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
+ 12345);
+ local_card_migration_manager_->GetMigratableCreditCards();
+
+ // Add 4 LocalCardMigration strikes.
+ LocalCardMigrationStrikeDatabase local_card_migration_strike_database =
+ LocalCardMigrationStrikeDatabase(strike_database_);
+ local_card_migration_strike_database.AddStrikes(4);
+ EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 4);
+
+ base::HistogramTester histogram_tester;
+
+ // Select the cards.
+ autofill_client_.set_migration_card_selections(
+ std::vector<std::string>{"guid1", "guid2"});
+ local_card_migration_manager_->AttemptToOfferLocalCardMigration(true);
+
+ // Verify that the strike count was logged when card migration accepted.
+ histogram_tester.ExpectBucketCount(
+ "Autofill.StrikeDatabase.StrikesPresentWhenLocalCardMigrationAccepted", 4,
+ 1);
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc b/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc
index 6125d447a75..5c204950aa7 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc
+++ b/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc
@@ -8,6 +8,13 @@
namespace autofill {
+const int LocalCardMigrationStrikeDatabase::kStrikesToRemoveWhenLocalCardAdded =
+ 2;
+const int LocalCardMigrationStrikeDatabase::kStrikesToAddWhenBubbleClosed = 2;
+const int LocalCardMigrationStrikeDatabase::kStrikesToAddWhenDialogClosed = 3;
+const int LocalCardMigrationStrikeDatabase::
+ kStrikesToAddWhenCardsDeselectedAtMigration = 3;
+
LocalCardMigrationStrikeDatabase::LocalCardMigrationStrikeDatabase(
StrikeDatabase* strike_database)
: StrikeDatabaseIntegratorBase(strike_database) {
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database.h b/chromium/components/autofill/core/browser/local_card_migration_strike_database.h
index ab25114d903..1124374313e 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database.h
+++ b/chromium/components/autofill/core/browser/local_card_migration_strike_database.h
@@ -18,6 +18,16 @@ class LocalCardMigrationStrikeDatabase : public StrikeDatabaseIntegratorBase {
LocalCardMigrationStrikeDatabase(StrikeDatabase* strike_database);
~LocalCardMigrationStrikeDatabase() override;
+ // Strikes to remove when user adds new local card.
+ static const int kStrikesToRemoveWhenLocalCardAdded;
+ // Strikes to add when user closes LocalCardMigrationBubble.
+ static const int kStrikesToAddWhenBubbleClosed;
+ // Strikes to add when user closes LocalCardMigrationDialog.
+ static const int kStrikesToAddWhenDialogClosed;
+ // Number of strikes to add when user de-selected some local cards during
+ // migration.
+ static const int kStrikesToAddWhenCardsDeselectedAtMigration;
+
std::string GetProjectPrefix() override;
int GetMaxStrikesLimit() override;
long long GetExpiryTimeMicros() override;
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc b/chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc
deleted file mode 100644
index c7d3ad022d5..00000000000
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database_unittest.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill/core/browser/local_card_migration_strike_database.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/autofill/core/browser/proto/strike_data.pb.h"
-#include "components/autofill/core/browser/test_autofill_clock.h"
-#include "components/autofill/core/browser/test_local_card_migration_strike_database.h"
-#include "components/autofill/core/common/autofill_clock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace autofill {
-
-class LocalCardMigrationStrikeDatabaseTest : public ::testing::Test {
- public:
- LocalCardMigrationStrikeDatabaseTest()
- : strike_database_(new StrikeDatabase(InitFilePath())) {}
-
- protected:
- base::HistogramTester* GetHistogramTester() { return &histogram_tester_; }
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- TestLocalCardMigrationStrikeDatabase strike_database_;
-
- private:
- static const base::FilePath InitFilePath() {
- base::ScopedTempDir temp_dir_;
- EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
- const base::FilePath file_path =
- temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest");
- return file_path;
- }
-
- base::HistogramTester histogram_tester_;
-};
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest, MaxStrikesLimitReachedTest) {
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
- // 3 strikes added.
- strike_database_.AddStrikes(3);
- EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
- // 4 strike added, total strike count is 7.
- strike_database_.AddStrikes(4);
- EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest,
- LocalCardMigrationNthStrikeAddedHistogram) {
- // 2 strikes logged.
- strike_database_.AddStrikes(2);
- strike_database_.RemoveStrikes(2);
- // 1 strike logged.
- strike_database_.AddStrike();
- // 2 strikes logged.
- strike_database_.AddStrike();
- std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
- "Autofill.StrikeDatabase.NthStrikeAdded.LocalCardMigration");
- // There should be two buckets, for strike counts of 1 and 2.
- ASSERT_EQ(2U, buckets.size());
- // Bucket for 1 strike should have count of 1.
- EXPECT_EQ(1, buckets[0].count);
- // Bucket for 2 strikes should have count of 2.
- EXPECT_EQ(2, buckets[1].count);
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest,
- AddStrikeForZeroAndNonZeroStrikesTest) {
- EXPECT_EQ(0, strike_database_.GetStrikes());
- strike_database_.AddStrike();
- EXPECT_EQ(1, strike_database_.GetStrikes());
- strike_database_.AddStrikes(2);
- EXPECT_EQ(3, strike_database_.GetStrikes());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest,
- ClearStrikesForNonZeroStrikesTest) {
- strike_database_.AddStrikes(3);
- EXPECT_EQ(3, strike_database_.GetStrikes());
- strike_database_.ClearStrikes();
- EXPECT_EQ(0, strike_database_.GetStrikes());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest, ClearStrikesForZeroStrikesTest) {
- strike_database_.ClearStrikes();
- EXPECT_EQ(0, strike_database_.GetStrikes());
-}
-
-TEST_F(LocalCardMigrationStrikeDatabaseTest, RemoveExpiredStrikesTest) {
- autofill::TestAutofillClock test_clock;
- test_clock.SetNow(AutofillClock::Now());
- strike_database_.AddStrikes(2);
- EXPECT_EQ(2, strike_database_.GetStrikes());
-
- // Advance clock to past expiry time.
- test_clock.Advance(base::TimeDelta::FromMicroseconds(
- strike_database_.GetExpiryTimeMicros() + 1));
-
- // One strike should be removed.
- strike_database_.RemoveExpiredStrikes();
- EXPECT_EQ(1, strike_database_.GetStrikes());
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc
new file mode 100644
index 00000000000..06674d12c2d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc
@@ -0,0 +1,91 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+
+namespace autofill {
+
+AddressFormEventLogger::AddressFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
+ : FormEventLoggerBase("Address",
+ is_in_main_frame,
+ form_interactions_ukm_logger) {}
+
+AddressFormEventLogger::~AddressFormEventLogger() = default;
+
+void AddressFormEventLogger::OnDidFillSuggestion(
+ const AutofillProfile& profile,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state) {
+ AutofillProfile::RecordType record_type = profile.record_type();
+ sync_state_ = sync_state;
+
+ form_interactions_ukm_logger_->LogDidFillSuggestion(
+ record_type,
+ /*is_for_for_credit_card=*/false, form, field);
+
+ if (record_type == AutofillProfile::SERVER_PROFILE) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_FILLED, form);
+ }
+
+ if (!has_logged_suggestion_filled_) {
+ has_logged_suggestion_filled_ = true;
+ logged_suggestion_filled_was_server_data_ =
+ record_type == AutofillProfile::SERVER_PROFILE;
+ Log(record_type == AutofillProfile::SERVER_PROFILE
+ ? FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
+ : FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ form);
+ }
+
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_FilledProfileSuggestion"));
+}
+
+void AddressFormEventLogger::OnDidSeeFillableDynamicForm(
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ Log(FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, form);
+}
+
+void AddressFormEventLogger::OnDidRefill(AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ Log(FORM_EVENT_DID_DYNAMIC_REFILL, form);
+}
+
+void AddressFormEventLogger::OnSubsequentRefillAttempt(
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ Log(FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, form);
+}
+
+void AddressFormEventLogger::RecordPollSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_PolledProfileSuggestions"));
+}
+
+void AddressFormEventLogger::RecordParseForm() {
+ base::RecordAction(base::UserMetricsAction("Autofill_ParsedProfileForm"));
+}
+
+void AddressFormEventLogger::RecordShowSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_ShowedProfileSuggestions"));
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h
new file mode 100644
index 00000000000..a115ffbde83
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h
@@ -0,0 +1,45 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_FORM_EVENT_LOGGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_FORM_EVENT_LOGGER_H_
+
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/metrics/form_event_logger_base.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+
+namespace autofill {
+
+class AddressFormEventLogger : public FormEventLoggerBase {
+ public:
+ AddressFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger);
+
+ ~AddressFormEventLogger() override;
+
+ void OnDidFillSuggestion(const AutofillProfile& profile,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state);
+
+ void OnDidSeeFillableDynamicForm(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ void OnDidRefill(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ void OnSubsequentRefillAttempt(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ protected:
+ void RecordPollSuggestions() override;
+ void RecordParseForm() override;
+ void RecordShowSuggestions() override;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_ADDRESS_FORM_EVENT_LOGGER_H_
diff --git a/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc
new file mode 100644
index 00000000000..ea19e7317b9
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc
@@ -0,0 +1,194 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/metrics/credit_card_form_event_logger.h"
+
+#include <string>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "components/autofill/core/browser/autofill_client.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_data_importer.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/validation.h"
+
+namespace autofill {
+
+CreditCardFormEventLogger::CreditCardFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
+ PersonalDataManager* personal_data_manager,
+ AutofillClient* client)
+ : FormEventLoggerBase("CreditCard",
+ is_in_main_frame,
+ form_interactions_ukm_logger),
+ personal_data_manager_(personal_data_manager),
+ client_(client) {}
+
+CreditCardFormEventLogger::~CreditCardFormEventLogger() = default;
+
+void CreditCardFormEventLogger::OnDidSelectMaskedServerCardSuggestion(
+ const FormStructure& form,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, form);
+ if (!has_logged_masked_server_card_suggestion_selected_) {
+ has_logged_masked_server_card_suggestion_selected_ = true;
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, form);
+ }
+}
+
+void CreditCardFormEventLogger::SetBankNameAvailable() {
+ has_logged_bank_name_available_ = true;
+}
+
+void CreditCardFormEventLogger::OnDidFillSuggestion(
+ const CreditCard& credit_card,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state) {
+ CreditCard::RecordType record_type = credit_card.record_type();
+ sync_state_ = sync_state;
+
+ form_interactions_ukm_logger_->LogDidFillSuggestion(
+ record_type,
+ /*is_for_credit_card=*/true, form, field);
+
+ if (record_type == CreditCard::MASKED_SERVER_CARD)
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, form);
+ else if (record_type == CreditCard::FULL_SERVER_CARD)
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED, form);
+ else
+ Log(FORM_EVENT_LOCAL_SUGGESTION_FILLED, form);
+
+ if (!has_logged_suggestion_filled_) {
+ has_logged_suggestion_filled_ = true;
+ logged_suggestion_filled_was_server_data_ =
+ record_type == CreditCard::MASKED_SERVER_CARD ||
+ record_type == CreditCard::FULL_SERVER_CARD;
+ logged_suggestion_filled_was_masked_server_card_ =
+ record_type == CreditCard::MASKED_SERVER_CARD;
+ if (record_type == CreditCard::MASKED_SERVER_CARD) {
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, form);
+ if (has_logged_bank_name_available_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
+ }
+ } else if (record_type == CreditCard::FULL_SERVER_CARD) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE, form);
+ if (has_logged_bank_name_available_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE);
+ }
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, form);
+ }
+ }
+
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_FilledCreditCardSuggestion"));
+}
+
+void CreditCardFormEventLogger::RecordPollSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_PolledCreditCardSuggestions"));
+}
+
+void CreditCardFormEventLogger::RecordParseForm() {
+ base::RecordAction(base::UserMetricsAction("Autofill_ParsedCreditCardForm"));
+}
+
+void CreditCardFormEventLogger::RecordShowSuggestions() {
+ base::RecordAction(
+ base::UserMetricsAction("Autofill_ShowedCreditCardSuggestions"));
+}
+
+void CreditCardFormEventLogger::LogWillSubmitForm(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else if (logged_suggestion_filled_was_masked_server_card_) {
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ }
+}
+
+void CreditCardFormEventLogger::LogFormSubmitted(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, form);
+ } else if (logged_suggestion_filled_was_masked_server_card_) {
+ Log(FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, form);
+ }
+}
+
+void CreditCardFormEventLogger::LogUkmInteractedWithForm(
+ FormSignature form_signature) {
+ form_interactions_ukm_logger_->LogInteractedWithForm(
+ /*is_for_credit_card=*/true, local_record_type_count_,
+ server_record_type_count_, form_signature);
+}
+
+void CreditCardFormEventLogger::OnSuggestionsShownOnce() {
+ if (has_logged_bank_name_available_) {
+ Log(FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE);
+ }
+}
+
+void CreditCardFormEventLogger::OnSuggestionsShownSubmittedOnce(
+ const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ const CreditCard credit_card =
+ client_->GetFormDataImporter()->ExtractCreditCardFromForm(form);
+ Log(GetCardNumberStatusFormEvent(credit_card), form);
+ }
+}
+
+void CreditCardFormEventLogger::OnLog(const std::string& name,
+ FormEvent event) const {
+ // Log in a different histogram for credit card forms on nonsecure pages so
+ // that form interactions on nonsecure pages can be analyzed on their own.
+ if (!is_context_secure_) {
+ base::UmaHistogramEnumeration(name + ".OnNonsecurePage", event,
+ NUM_FORM_EVENTS);
+ }
+}
+
+void CreditCardFormEventLogger::Log(BankNameDisplayedFormEvent event) const {
+ DCHECK_LT(event, BANK_NAME_NUM_FORM_EVENTS);
+ const std::string name("Autofill.FormEvents.CreditCard.BankNameDisplayed");
+ base::UmaHistogramEnumeration(name, event, BANK_NAME_NUM_FORM_EVENTS);
+}
+
+FormEvent CreditCardFormEventLogger::GetCardNumberStatusFormEvent(
+ const CreditCard& credit_card) {
+ const base::string16 number = credit_card.number();
+ FormEvent form_event =
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD;
+
+ if (number.empty()) {
+ form_event = FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD;
+ } else if (!HasCorrectLength(number)) {
+ form_event =
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD;
+ } else if (!PassesLuhnCheck(number)) {
+ form_event =
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD;
+ } else if (personal_data_manager_->IsKnownCard(credit_card)) {
+ form_event = FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD;
+ }
+
+ return form_event;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h
new file mode 100644
index 00000000000..67a16324dae
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h
@@ -0,0 +1,91 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_CREDIT_CARD_FORM_EVENT_LOGGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_CREDIT_CARD_FORM_EVENT_LOGGER_H_
+
+#include <string>
+
+#include "components/autofill/core/browser/autofill_client.h"
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/metrics/form_event_logger_base.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+
+namespace autofill {
+
+class CreditCardFormEventLogger : public FormEventLoggerBase {
+ public:
+ // Form Events for autofill with bank name available for display.
+ enum BankNameDisplayedFormEvent {
+ // A dropdown with suggestions was shown and at least one suggestion has a
+ // bank name. Logged at most once per page load.
+ FORM_EVENT_SUGGESTIONS_SHOWN_WITH_BANK_NAME_AVAILABLE_ONCE = 0,
+ // A server suggestion was used to fill the form and at least one suggestion
+ // has a bank name. Logged at most once per page load.
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_WITH_BANK_NAME_AVAILABLE_ONCE,
+ BANK_NAME_NUM_FORM_EVENTS,
+ };
+
+ CreditCardFormEventLogger(
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
+ PersonalDataManager* personal_data_manager,
+ AutofillClient* client);
+
+ ~CreditCardFormEventLogger() override;
+
+ inline void set_is_context_secure(bool is_context_secure) {
+ is_context_secure_ = is_context_secure;
+ }
+
+ void OnDidSelectMaskedServerCardSuggestion(
+ const FormStructure& form,
+ AutofillSyncSigninState sync_state);
+
+ void SetBankNameAvailable();
+
+ // In case of masked cards, caller must make sure this gets called before
+ // the card is upgraded to a full card.
+ void OnDidFillSuggestion(const CreditCard& credit_card,
+ const FormStructure& form,
+ const AutofillField& field,
+ AutofillSyncSigninState sync_state);
+
+ protected:
+ // FormEventLoggerBase pure-virtual overrides.
+ void RecordPollSuggestions() override;
+ void RecordParseForm() override;
+ void RecordShowSuggestions() override;
+
+ // FormEventLoggerBase virtual overrides.
+ void LogWillSubmitForm(const FormStructure& form) override;
+ void LogFormSubmitted(const FormStructure& form) override;
+ void LogUkmInteractedWithForm(FormSignature form_signature) override;
+ void OnSuggestionsShownOnce() override;
+ void OnSuggestionsShownSubmittedOnce(const FormStructure& form) override;
+ void OnLog(const std::string& name, FormEvent event) const override;
+
+ // Bringing base class' Log function into scope to allow overloading.
+ using FormEventLoggerBase::Log;
+
+ private:
+ void Log(BankNameDisplayedFormEvent event) const;
+ FormEvent GetCardNumberStatusFormEvent(const CreditCard& credit_card);
+
+ bool is_context_secure_ = false;
+ bool has_logged_bank_name_available_ = false;
+ bool has_logged_masked_server_card_suggestion_selected_ = false;
+ bool logged_suggestion_filled_was_masked_server_card_ = false;
+
+ // Weak references.
+ PersonalDataManager* personal_data_manager_;
+ AutofillClient* client_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_CREDIT_CARD_FORM_EVENT_LOGGER_H_
diff --git a/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc
new file mode 100644
index 00000000000..99025b5070b
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc
@@ -0,0 +1,199 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/metrics/form_event_logger_base.h"
+
+#include <string>
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "base/time/time.h"
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/sync_utils.h"
+#include "components/autofill/core/common/form_field_data.h"
+#include "components/autofill/core/common/signatures_util.h"
+
+namespace autofill {
+
+FormEventLoggerBase::FormEventLoggerBase(
+ const std::string& form_type_name,
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
+ : form_type_name_(form_type_name),
+ is_in_main_frame_(is_in_main_frame),
+ form_interactions_ukm_logger_(form_interactions_ukm_logger) {}
+
+FormEventLoggerBase::~FormEventLoggerBase() = default;
+
+void FormEventLoggerBase::OnDidInteractWithAutofillableForm(
+ const FormStructure& form,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+ if (!has_logged_interacted_) {
+ has_logged_interacted_ = true;
+ LogUkmInteractedWithForm(form.form_signature());
+ Log(FORM_EVENT_INTERACTED_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::OnDidPollSuggestions(
+ const FormFieldData& field,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+ // Record only one poll user action for consecutive polls of the same field.
+ // This is to avoid recording too many poll actions (for example when a user
+ // types in a field, triggering multiple queries) to make the analysis more
+ // simple.
+ if (!field.SameFieldAs(last_polled_field_)) {
+ RecordPollSuggestions();
+ last_polled_field_ = field;
+ }
+}
+
+void FormEventLoggerBase::OnDidParseForm(const FormStructure& form) {
+ Log(FORM_EVENT_DID_PARSE_FORM, form);
+ RecordParseForm();
+}
+
+void FormEventLoggerBase::OnPopupSuppressed(const FormStructure& form,
+ const AutofillField& field) {
+ Log(FORM_EVENT_POPUP_SUPPRESSED, form);
+ if (!has_logged_popup_suppressed_) {
+ has_logged_popup_suppressed_ = true;
+ Log(FORM_EVENT_POPUP_SUPPRESSED_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::OnDidShowSuggestions(
+ const FormStructure& form,
+ const AutofillField& field,
+ const base::TimeTicks& form_parsed_timestamp,
+ AutofillSyncSigninState sync_state) {
+ sync_state_ = sync_state;
+ form_interactions_ukm_logger_->LogSuggestionsShown(form, field,
+ form_parsed_timestamp);
+
+ Log(FORM_EVENT_SUGGESTIONS_SHOWN, form);
+ if (!has_logged_suggestions_shown_) {
+ has_logged_suggestions_shown_ = true;
+ Log(FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, form);
+ OnSuggestionsShownOnce();
+ }
+
+ RecordShowSuggestions();
+}
+
+void FormEventLoggerBase::OnWillSubmitForm(AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ // Not logging this kind of form if we haven't logged a user interaction.
+ if (!has_logged_interacted_)
+ return;
+
+ // Not logging twice.
+ if (has_logged_will_submit_)
+ return;
+ has_logged_will_submit_ = true;
+
+ LogWillSubmitForm(form);
+
+ if (has_logged_suggestions_shown_) {
+ Log(FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, form);
+ }
+
+ base::RecordAction(base::UserMetricsAction("Autofill_OnWillSubmitForm"));
+}
+
+void FormEventLoggerBase::OnFormSubmitted(bool force_logging,
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form) {
+ sync_state_ = sync_state;
+ // Not logging this kind of form if we haven't logged a user interaction.
+ if (!has_logged_interacted_)
+ return;
+
+ // Not logging twice.
+ if (has_logged_submitted_)
+ return;
+ has_logged_submitted_ = true;
+
+ LogFormSubmitted(form);
+
+ if (has_logged_suggestions_shown_ || force_logging) {
+ Log(FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, form);
+ OnSuggestionsShownSubmittedOnce(form);
+ }
+}
+
+void FormEventLoggerBase::Log(FormEvent event,
+ const FormStructure& form) const {
+ DCHECK_LT(event, NUM_FORM_EVENTS);
+ std::string name("Autofill.FormEvents." + form_type_name_);
+ base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
+
+ // Log UKM metrics for only autofillable form events.
+ if (form.IsAutofillable()) {
+ form_interactions_ukm_logger_->LogFormEvent(event, form.GetFormTypes(),
+ form.form_parsed_timestamp());
+ }
+
+ // Log again in a different histogram so that iframes can be analyzed on
+ // their own.
+ base::UmaHistogramEnumeration(
+ name + (is_in_main_frame_ ? ".IsInMainFrame" : ".IsInIFrame"), event,
+ NUM_FORM_EVENTS);
+
+ // Allow specialized type of logging.
+ OnLog(name, event);
+
+ // Logging again in a different histogram for segmentation purposes.
+ if (server_record_type_count_ == 0 && local_record_type_count_ == 0)
+ name += ".WithNoData";
+ else if (server_record_type_count_ > 0 && local_record_type_count_ == 0)
+ name += ".WithOnlyServerData";
+ else if (server_record_type_count_ == 0 && local_record_type_count_ > 0)
+ name += ".WithOnlyLocalData";
+ else
+ name += ".WithBothServerAndLocalData";
+ base::UmaHistogramEnumeration(name, event, NUM_FORM_EVENTS);
+ base::UmaHistogramEnumeration(
+ name + AutofillMetrics::GetMetricsSyncStateSuffix(sync_state_), event,
+ NUM_FORM_EVENTS);
+}
+
+void FormEventLoggerBase::LogWillSubmitForm(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::LogFormSubmitted(const FormStructure& form) {
+ if (!has_logged_suggestion_filled_) {
+ Log(FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, form);
+ } else if (logged_suggestion_filled_was_server_data_) {
+ Log(FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, form);
+ } else {
+ Log(FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, form);
+ }
+}
+
+void FormEventLoggerBase::LogUkmInteractedWithForm(
+ FormSignature form_signature) {
+ form_interactions_ukm_logger_->LogInteractedWithForm(
+ /*is_for_credit_card=*/false, local_record_type_count_,
+ server_record_type_count_, form_signature);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h
new file mode 100644
index 00000000000..173df3b0ddd
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h
@@ -0,0 +1,107 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENT_LOGGER_BASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENT_LOGGER_BASE_H_
+
+#include <string>
+
+#include "components/autofill/core/browser/autofill_data_model.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/metrics/form_events.h"
+#include "components/autofill/core/browser/sync_utils.h"
+#include "components/autofill/core/common/form_field_data.h"
+
+namespace autofill {
+
+// Utility to log autofill form events in the relevant histograms depending on
+// the presence of server and/or local data.
+class FormEventLoggerBase {
+ public:
+ FormEventLoggerBase(
+ const std::string& form_type_name,
+ bool is_in_main_frame,
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger);
+
+ inline void set_server_record_type_count(size_t server_record_type_count) {
+ server_record_type_count_ = server_record_type_count;
+ }
+
+ inline void set_local_record_type_count(size_t local_record_type_count) {
+ local_record_type_count_ = local_record_type_count;
+ }
+
+ void OnDidInteractWithAutofillableForm(const FormStructure& form,
+ AutofillSyncSigninState sync_state);
+
+ void OnDidPollSuggestions(const FormFieldData& field,
+ AutofillSyncSigninState sync_state);
+
+ void OnDidParseForm(const FormStructure& form);
+
+ void OnPopupSuppressed(const FormStructure& form, const AutofillField& field);
+
+ void OnDidShowSuggestions(const FormStructure& form,
+ const AutofillField& field,
+ const base::TimeTicks& form_parsed_timestamp,
+ AutofillSyncSigninState sync_state);
+
+ void OnWillSubmitForm(AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ void OnFormSubmitted(bool force_logging,
+ AutofillSyncSigninState sync_state,
+ const FormStructure& form);
+
+ protected:
+ virtual ~FormEventLoggerBase();
+
+ void Log(FormEvent event, const FormStructure& form) const;
+
+ virtual void RecordPollSuggestions() = 0;
+ virtual void RecordParseForm() = 0;
+ virtual void RecordShowSuggestions() = 0;
+
+ virtual void LogWillSubmitForm(const FormStructure& form);
+ virtual void LogFormSubmitted(const FormStructure& form);
+
+ // Only used for UKM backward compatibility since it depends on IsCreditCard.
+ // TODO (crbug.com/925913): Remove IsCreditCard from UKM logs amd replace with
+ // |form_type_name_|.
+ virtual void LogUkmInteractedWithForm(FormSignature form_signature);
+
+ virtual void OnSuggestionsShownOnce() {}
+ virtual void OnSuggestionsShownSubmittedOnce(const FormStructure& form) {}
+ virtual void OnLog(const std::string& name, FormEvent event) const {}
+
+ // Constructor parameters.
+ std::string form_type_name_;
+ bool is_in_main_frame_;
+
+ // State variables.
+ size_t server_record_type_count_ = 0;
+ size_t local_record_type_count_ = 0;
+ bool has_logged_interacted_ = false;
+ bool has_logged_popup_suppressed_ = false;
+ bool has_logged_suggestions_shown_ = false;
+ bool has_logged_suggestion_filled_ = false;
+ bool has_logged_will_submit_ = false;
+ bool has_logged_submitted_ = false;
+ bool logged_suggestion_filled_was_server_data_ = false;
+
+ // The last field that was polled for suggestions.
+ FormFieldData last_polled_field_;
+
+ // Weak reference.
+ AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger_;
+
+ AutofillSyncSigninState sync_state_ = AutofillSyncSigninState::kNumSyncStates;
+};
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENT_LOGGER_BASE_H_
diff --git a/chromium/components/autofill/core/browser/metrics/form_events.h b/chromium/components/autofill/core/browser/metrics/form_events.h
new file mode 100644
index 00000000000..40cbbe0517d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/metrics/form_events.h
@@ -0,0 +1,97 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENTS_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENTS_H_
+
+namespace autofill {
+
+// Form Events for autofill.
+// These events are triggered separetly for address and credit card forms.
+enum FormEvent {
+ // User interacted with a field of this kind of form. Logged only once per
+ // page load.
+ FORM_EVENT_INTERACTED_ONCE = 0,
+ // A dropdown with suggestions was shown.
+ FORM_EVENT_SUGGESTIONS_SHOWN,
+ // Same as above, but recoreded only once per page load.
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE,
+ // A local suggestion was used to fill the form.
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED,
+ // A server suggestion was used to fill the form.
+ // When dealing with credit cards, this means a full server card was used
+ // to fill.
+ FORM_EVENT_SERVER_SUGGESTION_FILLED,
+ // A masked server card suggestion was used to fill the form.
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED,
+ // A suggestion was used to fill the form. The origin type (local or server
+ // or masked server card) of the first selected within a page load will
+ // determine which of the following two will be fired.
+ FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE,
+ FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE,
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE,
+ // A form was submitted. Depending on the user filling a local, server,
+ // masked server card or no suggestion one of the following will be
+ // triggered. Only one of the following four will be triggered per page
+ // load.
+ FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE,
+ FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE,
+ FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE,
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE,
+ // A masked server card suggestion was selected to fill the form.
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED,
+ // Same as above but only triggered once per page load.
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE,
+ // An autofillable form is about to be submitted. If the submission is not
+ // interrupted by JavaScript, the "form submitted" events above will also be
+ // logged. Depending on the user filling a local, server, masked server card
+ // or no suggestion one of the following will be triggered, at most once per
+ // page load.
+ FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE,
+ FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE,
+ FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE,
+ FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE,
+ // A dropdown with suggestions was shown and a form was submitted after
+ // that.
+ FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE,
+ // A dropdown with suggestions was shown and a form is about to be
+ // submitted. If the submission is not interrupted by JavaScript, the "form
+ // submitted" event above will also be logged.
+ FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE,
+ // A dropdown with credit card suggestions was shown, but they were not used
+ // to fill the form. Depending on the user submitting a card known by the
+ // browser, submitting a card that the browser does not know about,
+ // submitting with an empty card number, submitting with a card number of
+ // wrong size or submitting with a card number that does not pass luhn
+ // check, one of the following will be triggered. At most one of the
+ // following five metrics will be triggered per submit.
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_KNOWN_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_UNKNOWN_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_NO_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_WRONG_SIZE_CARD,
+ FORM_EVENT_SUBMIT_WITHOUT_SELECTING_SUGGESTIONS_FAIL_LUHN_CHECK_CARD,
+
+ // The form was changed dynamically. This value has been deprecated.
+ FORM_EVENT_DID_SEE_DYNAMIC_FORM,
+ // The form was changed dynamically and was fillable.
+ FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM,
+ // There was a dynamic change of the form and it got re-filled
+ // automatically.
+ FORM_EVENT_DID_DYNAMIC_REFILL,
+ // The form dynamically changed another time after the refill.
+ FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL,
+ // The popup was suppressed because the native view couldn't be created.
+ FORM_EVENT_POPUP_SUPPRESSED,
+ // Same as above, but recoreded only once per page load.
+ FORM_EVENT_POPUP_SUPPRESSED_ONCE,
+
+ // The form was parsed.
+ FORM_EVENT_DID_PARSE_FORM,
+
+ NUM_FORM_EVENTS,
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_FORM_EVENTS_H_ \ No newline at end of file
diff --git a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc b/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc
index 2c065752666..ff4367110f0 100644
--- a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc
+++ b/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/password_requirements_spec_fetcher_impl.h"
+#include "base/bind.h"
#include "base/logging.h"
#include "base/md5.h"
#include "base/metrics/histogram_functions.h"
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.cc b/chromium/components/autofill/core/browser/payments/payments_client.cc
index ac4803ae4a3..3fda27d89e6 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_client.cc
@@ -8,6 +8,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
@@ -342,7 +343,8 @@ class GetUploadDetailsRequest : public PaymentsRequest {
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
PaymentsClient::UploadCardSource upload_card_source)
: addresses_(addresses),
@@ -441,6 +443,16 @@ class GetUploadDetailsRequest : public PaymentsRequest {
base::Value* dictionary_value = response.FindKey("legal_message");
if (dictionary_value)
legal_message_ = std::make_unique<base::Value>(dictionary_value->Clone());
+
+ base::Value* list_ptr = response.FindKey("supported_card_bin_ranges");
+ if (list_ptr && list_ptr->is_list()) {
+ for (base::Value& result : list_ptr->GetList()) {
+ DCHECK(result.is_dict());
+ base::Optional<int> start = response.FindIntKey("start");
+ base::Optional<int> end = response.FindIntKey("end");
+ supported_card_bin_ranges_.push_back(std::make_pair(*start, *end));
+ }
+ }
}
bool IsResponseComplete() override {
@@ -448,7 +460,8 @@ class GetUploadDetailsRequest : public PaymentsRequest {
}
void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override {
- std::move(callback_).Run(result, context_token_, std::move(legal_message_));
+ std::move(callback_).Run(result, context_token_, std::move(legal_message_),
+ supported_card_bin_ranges_);
}
private:
@@ -459,10 +472,12 @@ class GetUploadDetailsRequest : public PaymentsRequest {
std::string app_locale_;
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)>
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)>
callback_;
base::string16 context_token_;
std::unique_ptr<base::Value> legal_message_;
+ std::vector<std::pair<int, int>> supported_card_bin_ranges_;
const int billable_service_number_;
PaymentsClient::UploadCardSource upload_card_source_;
};
@@ -770,7 +785,8 @@ void PaymentsClient::GetUploadDetails(
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
UploadCardSource upload_card_source) {
IssueRequest(
@@ -845,11 +861,11 @@ void PaymentsClient::InitializeResourceRequest() {
// Add Chrome experiment state to the request headers.
net::HttpRequestHeaders headers;
// User is always signed-in to be able to upload card to Google Payments.
- variations::AppendVariationHeaders(
+ variations::AppendVariationsHeader(
resource_request_->url,
is_off_the_record_ ? variations::InIncognito::kYes
: variations::InIncognito::kNo,
- variations::SignedIn::kYes, &resource_request_->headers);
+ variations::SignedIn::kYes, resource_request_.get());
}
}
@@ -878,7 +894,8 @@ void PaymentsClient::OnSimpleLoaderCompleteInternal(int response_code,
// Valid response.
case net::HTTP_OK: {
std::string error_code;
- std::unique_ptr<base::Value> message_value = base::JSONReader::Read(data);
+ std::unique_ptr<base::Value> message_value =
+ base::JSONReader::ReadDeprecated(data);
if (message_value.get() && message_value->is_dict()) {
response_dict =
base::Value::FromUniquePtrValue(std::move(message_value));
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.h b/chromium/components/autofill/core/browser/payments/payments_client.h
index be0bc533999..ad6c075aa75 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.h
+++ b/chromium/components/autofill/core/browser/payments/payments_client.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_CLIENT_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_CLIENT_H_
+#include <utility>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
@@ -178,7 +180,8 @@ class PaymentsClient {
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
UploadCardSource upload_card_source =
UploadCardSource::UNKNOWN_UPLOAD_CARD_SOURCE);
diff --git a/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc b/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
index 1b733047735..6f9edcede0d 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -5,6 +5,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
@@ -24,6 +25,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
+#include "components/variations/net/variations_http_headers.h"
#include "components/variations/variations_associated_data.h"
#include "components/variations/variations_http_header_provider.h"
#include "services/identity/public/cpp/identity_test_environment.h"
@@ -64,11 +66,13 @@ class PaymentsClientTest : public testing::Test {
server_id_.clear();
real_pan_.clear();
legal_message_.reset();
+ has_variations_header_ = false;
factory()->SetInterceptor(base::BindLambdaForTesting(
[&](const network::ResourceRequest& request) {
intercepted_headers_ = request.headers;
intercepted_body_ = network::GetUploadData(request);
+ has_variations_header_ = variations::HasVariationsHeader(request);
}));
test_shared_loader_factory_ =
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
@@ -115,11 +119,14 @@ class PaymentsClientTest : public testing::Test {
real_pan_ = real_pan;
}
- void OnDidGetUploadDetails(AutofillClient::PaymentsRpcResult result,
- const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ void OnDidGetUploadDetails(
+ AutofillClient::PaymentsRpcResult result,
+ const base::string16& context_token,
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_card_bin_ranges) {
result_ = result;
legal_message_ = std::move(legal_message);
+ supported_card_bin_ranges_ = supported_card_bin_ranges;
}
void OnDidUploadCard(AutofillClient::PaymentsRpcResult result,
@@ -207,7 +214,7 @@ class PaymentsClientTest : public testing::Test {
const std::string& GetUploadData() { return intercepted_body_; }
- net::HttpRequestHeaders* GetRequestHeaders() { return &intercepted_headers_; }
+ bool HasVariationsHeader() { return has_variations_header_; }
// Issues access token in response to any access token request. This will
// start the Payments Request which requires the authentication.
@@ -233,6 +240,7 @@ class PaymentsClientTest : public testing::Test {
std::string server_id_;
std::string real_pan_;
std::unique_ptr<base::Value> legal_message_;
+ std::vector<std::pair<int, int>> supported_card_bin_ranges_;
std::vector<MigratableCreditCard> migratable_credit_cards_;
std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_;
std::string display_text_;
@@ -245,6 +253,7 @@ class PaymentsClientTest : public testing::Test {
identity::IdentityTestEnvironment identity_test_env_;
net::HttpRequestHeaders intercepted_headers_;
+ bool has_variations_header_;
std::string intercepted_body_;
base::WeakPtrFactory<PaymentsClientTest> weak_ptr_factory_;
@@ -536,10 +545,8 @@ TEST_F(PaymentsClientTest, GetUploadDetailsVariationsTest) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartGettingUploadDetails();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -554,10 +561,8 @@ TEST_F(PaymentsClientTest, GetUploadDetailsVariationsTestExperimentFlagOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartGettingUploadDetails();
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -572,10 +577,8 @@ TEST_F(PaymentsClientTest, UploadCardVariationsTest) {
StartUploading(/*include_cvc=*/true);
IssueOAuthToken();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -590,10 +593,8 @@ TEST_F(PaymentsClientTest, UploadCardVariationsTestExperimentFlagOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartUploading(/*include_cvc=*/true);
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -608,10 +609,8 @@ TEST_F(PaymentsClientTest, UnmaskCardVariationsTest) {
StartUnmasking();
IssueOAuthToken();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -626,10 +625,8 @@ TEST_F(PaymentsClientTest, UnmaskCardVariationsTestExperimentOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartUnmasking();
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -645,10 +642,8 @@ TEST_F(PaymentsClientTest, MigrateCardsVariationsTest) {
StartMigrating(/*has_cardholder_name=*/true);
IssueOAuthToken();
- std::string value;
- EXPECT_TRUE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_FALSE(value.empty());
+ EXPECT_TRUE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
@@ -663,10 +658,8 @@ TEST_F(PaymentsClientTest, MigrateCardsVariationsTestExperimentFlagOff) {
CreateFieldTrialWithId("AutofillTest", "Group", 369);
StartMigrating(/*has_cardholder_name=*/true);
- std::string value;
- EXPECT_FALSE(GetRequestHeaders()->GetHeader("X-Client-Data", &value));
// Note that experiment information is stored in X-Client-Data.
- EXPECT_TRUE(value.empty());
+ EXPECT_FALSE(HasVariationsHeader());
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
diff --git a/chromium/components/autofill/core/browser/payments/test_payments_client.cc b/chromium/components/autofill/core/browser/payments/test_payments_client.cc
index 8bf0f86a13d..e58fe67248f 100644
--- a/chromium/components/autofill/core/browser/payments/test_payments_client.cc
+++ b/chromium/components/autofill/core/browser/payments/test_payments_client.cc
@@ -30,7 +30,8 @@ void TestPaymentsClient::GetUploadDetails(
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
PaymentsClient::UploadCardSource upload_card_source) {
upload_details_addresses_ = addresses;
@@ -38,11 +39,11 @@ void TestPaymentsClient::GetUploadDetails(
active_experiments_ = active_experiments;
billable_service_number_ = billable_service_number;
upload_card_source_ = upload_card_source;
- std::move(callback).Run(app_locale == "en-US"
- ? AutofillClient::SUCCESS
- : AutofillClient::PERMANENT_FAILURE,
- base::ASCIIToUTF16("this is a context token"),
- std::unique_ptr<base::Value>(nullptr));
+ std::move(callback).Run(
+ app_locale == "en-US" ? AutofillClient::SUCCESS
+ : AutofillClient::PERMANENT_FAILURE,
+ base::ASCIIToUTF16("this is a context token"),
+ std::unique_ptr<base::Value>(nullptr), supported_card_bin_ranges_);
}
void TestPaymentsClient::UploadCard(
@@ -71,5 +72,10 @@ void TestPaymentsClient::SetSaveResultForCardsMigration(
save_result_ = std::move(save_result);
}
+void TestPaymentsClient::SetSupportedBINRanges(
+ std::vector<std::pair<int, int>> bin_ranges) {
+ supported_card_bin_ranges_ = bin_ranges;
+}
+
} // namespace payments
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/payments/test_payments_client.h b/chromium/components/autofill/core/browser/payments/test_payments_client.h
index 01e9d008903..e7f6c928e48 100644
--- a/chromium/components/autofill/core/browser/payments/test_payments_client.h
+++ b/chromium/components/autofill/core/browser/payments/test_payments_client.h
@@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_PAYMENTS_CLIENT_H_
#include <string>
+#include <utility>
#include <vector>
#include "components/autofill/core/browser/payments/payments_client.h"
@@ -34,7 +35,8 @@ class TestPaymentsClient : public payments::PaymentsClient {
const std::string& app_locale,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
const base::string16&,
- std::unique_ptr<base::Value>)> callback,
+ std::unique_ptr<base::Value>,
+ std::vector<std::pair<int, int>>)> callback,
const int billable_service_number,
UploadCardSource upload_card_source =
UploadCardSource::UNKNOWN_UPLOAD_CARD_SOURCE) override;
@@ -55,6 +57,8 @@ class TestPaymentsClient : public payments::PaymentsClient {
std::unique_ptr<std::unordered_map<std::string, std::string>>
save_result);
+ void SetSupportedBINRanges(std::vector<std::pair<int, int>> bin_ranges);
+
int detected_values_in_upload_details() const { return detected_values_; }
const std::vector<AutofillProfile>& addresses_in_upload_details() const {
return upload_details_addresses_;
@@ -74,6 +78,7 @@ class TestPaymentsClient : public payments::PaymentsClient {
private:
std::string server_id_;
+ std::vector<std::pair<int, int>> supported_card_bin_ranges_;
std::vector<AutofillProfile> upload_details_addresses_;
std::vector<AutofillProfile> upload_card_addresses_;
int detected_values_;
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.cc b/chromium/components/autofill/core/browser/personal_data_manager.cc
index 7c66782f7a5..902884a4b06 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager.cc
@@ -13,6 +13,7 @@
#include <string>
#include <utility>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/feature_list.h"
#include "base/i18n/case_conversion.h"
@@ -268,7 +269,6 @@ void PersonalDataManager::Init(
identity::IdentityManager* identity_manager,
AutofillProfileValidator* client_profile_validator,
history::HistoryService* history_service,
- GaiaCookieManagerService* cookie_manager_service,
bool is_off_the_record) {
CountryNames::SetLocaleString(app_locale_);
database_helper_->Init(profile_database, account_database);
@@ -287,12 +287,11 @@ void PersonalDataManager::Init(
if (history_service_)
history_service_->AddObserver(this);
- // Listen for cookie deletion by the user.
- cookie_manager_service_ = cookie_manager_service;
- if (cookie_manager_service_)
- cookie_manager_service_->AddObserver(this);
-
+ // Listen for account cookie deletion by the user.
identity_manager_ = identity_manager;
+ if (identity_manager_)
+ identity_manager_->AddObserver(this);
+
is_off_the_record_ = is_off_the_record;
if (!is_off_the_record_)
@@ -340,9 +339,9 @@ void PersonalDataManager::Shutdown() {
history_service_->RemoveObserver(this);
history_service_ = nullptr;
- if (cookie_manager_service_)
- cookie_manager_service_->RemoveObserver(this);
- cookie_manager_service_ = nullptr;
+ if (identity_manager_)
+ identity_manager_->RemoveObserver(this);
+ identity_manager_ = nullptr;
}
void PersonalDataManager::OnSyncServiceInitialized(
@@ -483,16 +482,12 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
}
is_data_loaded_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " refresh is done, notifying PersonalDataChanged";
NotifyPersonalDataChanged();
}
}
void PersonalDataManager::AutofillMultipleChanged() {
has_synced_new_data_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " has synced new data, refreshing";
Refresh();
}
@@ -536,7 +531,7 @@ void PersonalDataManager::OnSyncShutdown(syncer::SyncService* sync_service) {
sync_service_ = nullptr;
}
-AccountInfo PersonalDataManager::GetAccountInfoForPaymentsServer() const {
+CoreAccountInfo PersonalDataManager::GetAccountInfoForPaymentsServer() const {
// If butter is enabled or the feature to get the Payment Identity from Sync
// is enabled, return the account of the active signed-in user irrespective of
// whether they enabled sync or not.
@@ -558,7 +553,7 @@ bool PersonalDataManager::IsSyncFeatureEnabled() const {
!database_helper_->IsUsingAccountStorageForServerData();
}
-void PersonalDataManager::OnGaiaCookieDeletedByUserAction() {
+void PersonalDataManager::OnAccountsCookieDeletedByUserAction() {
// Clear all the Sync Transport feature opt-ins.
::autofill::prefs::ClearSyncTransportOptIns(pref_service_);
}
@@ -630,19 +625,19 @@ void PersonalDataManager::RecordUseOf(const AutofillDataModel& data_model) {
AutofillProfile* profile = GetProfileByGUID(data_model.guid());
if (profile) {
- if (profile->record_type() == AutofillProfile::LOCAL_PROFILE) {
- // We can't make the change directly on the web_profiles_, the update
- // should happen in the database first.
- AutofillProfile updated_profile(*profile);
- updated_profile.RecordAndLogUse();
- UpdateProfileInDB(updated_profile);
- } else if (profile->record_type() == AutofillProfile::SERVER_PROFILE) {
- profile->RecordAndLogUse();
- // TODO(crbug.com/864519): Update this once addresses support account
- // storage, and also use the server database.
- database_helper_->GetLocalDatabase()->UpdateServerAddressMetadata(
- *profile);
- Refresh();
+ profile->RecordAndLogUse();
+
+ switch (profile->record_type()) {
+ case AutofillProfile::LOCAL_PROFILE:
+ UpdateProfileInDB(*profile, /*enforced=*/true);
+ break;
+ case AutofillProfile::SERVER_PROFILE:
+ DCHECK(database_helper_->GetServerDatabase())
+ << "Recording use of server address without server storage.";
+ database_helper_->GetServerDatabase()->UpdateServerAddressMetadata(
+ *profile);
+ Refresh();
+ break;
}
}
}
@@ -1006,19 +1001,45 @@ void PersonalDataManager::UpdateClientValidityStates(
bool update_validation =
pref_service_->GetInteger(prefs::kAutofillLastVersionValidated) <
CHROME_VERSION_MAJOR;
+
+ DVLOG(1) << "Autofill profile client validation "
+ << (update_validation ? "needs to be" : "has already been")
+ << " performed for this version";
+
for (const auto* profile : profiles) {
if (!profile->is_client_validity_states_updated() || update_validation) {
+ profile->set_is_client_validity_states_updated(false);
+ ongoing_profile_changes_[profile->guid()].push_back(
+ AutofillProfileDeepChange(AutofillProfileChange::UPDATE, *profile));
+ ongoing_profile_changes_[profile->guid()].back().set_enforce_update();
client_profile_validator_->StartProfileValidation(
profile, base::BindOnce(&PersonalDataManager::OnValidated,
weak_factory_.GetWeakPtr()));
}
}
+
// Set the pref to the current major version if already not set.
if (update_validation)
pref_service_->SetInteger(prefs::kAutofillLastVersionValidated,
CHROME_VERSION_MAJOR);
}
+bool PersonalDataManager::UpdateClientValidityStates(
+ const AutofillProfile& profile) {
+ if (!base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileClientValidation) ||
+ !client_profile_validator_ ||
+ profile.is_client_validity_states_updated()) {
+ OnValidated(&profile);
+ return false;
+ }
+
+ client_profile_validator_->StartProfileValidation(
+ &profile, base::BindOnce(&PersonalDataManager::OnValidated,
+ weak_factory_.GetWeakPtr()));
+ return true;
+}
+
std::vector<AutofillProfile*> PersonalDataManager::GetServerProfiles() const {
std::vector<AutofillProfile*> result;
if (!IsAutofillProfileEnabled())
@@ -1078,55 +1099,30 @@ std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest()
std::vector<AutofillProfile*> profiles = GetProfiles();
- // Rank the suggestions by frecency (see AutofillDataModel for details).
+ bool use_server_validation = base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileServerValidation);
+ bool use_client_validation = base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileClientValidation);
+
+ // Rank the suggestions by frescocency (see AutofillDataModel for details).
+ // Frescocency is frecency + validity score.
const base::Time comparison_time = AutofillClock::Now();
std::sort(profiles.begin(), profiles.end(),
- [comparison_time](const AutofillDataModel* a,
- const AutofillDataModel* b) {
- return a->CompareFrecency(b, comparison_time);
+ [comparison_time, use_client_validation, use_server_validation](
+ const AutofillProfile* a, const AutofillProfile* b) {
+ return a->HasGreaterFrescocencyThan(b, comparison_time,
+ use_client_validation,
+ use_server_validation);
});
return profiles;
}
-// static
-void PersonalDataManager::MaybeRemoveInvalidSuggestions(
- const AutofillType& type,
- std::vector<AutofillProfile*>* profiles) {
- const bool suggest_invalid = base::FeatureList::IsEnabled(
- features::kAutofillSuggestInvalidProfileData);
-
- for (size_t i = 0; i < profiles->size(); ++i) {
- bool is_client_invalid =
- (*profiles)[i]->GetValidityState(type.GetStorableType(),
- AutofillProfile::CLIENT) ==
- AutofillProfile::INVALID;
-
- bool is_server_invalid =
- (*profiles)[i]->GetValidityState(type.GetStorableType(),
- AutofillProfile::SERVER) ==
- AutofillProfile::INVALID;
-
- if ((is_server_invalid || is_client_invalid) && !suggest_invalid)
- (*profiles)[i] = nullptr;
- if (is_server_invalid || is_client_invalid)
- UMA_HISTOGRAM_BOOLEAN("Autofill.InvalidProfileData.UsedForSuggestion",
- suggest_invalid);
- }
-
- if (!suggest_invalid) {
- profiles->erase(
- std::stable_partition(profiles->begin(), profiles->end(),
- [](AutofillProfile* p) { return p != nullptr; }),
- profiles->end());
- }
-}
-
std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
const AutofillType& type,
const base::string16& field_contents,
bool field_is_autofilled,
- const std::vector<ServerFieldType>& other_field_types) {
+ const std::vector<ServerFieldType>& field_types) {
if (IsInAutofillSuggestionsDisabledExperiment())
return std::vector<Suggestion>();
@@ -1134,6 +1130,11 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
base::string16 field_contents_canon =
comparator.NormalizeForComparison(field_contents);
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillProfileServerValidation)) {
+ UpdateProfilesServerValidityMapsIfNeeded(GetProfiles());
+ }
+
// Get the profiles to suggest, which are already sorted.
std::vector<AutofillProfile*> sorted_profiles = GetProfilesToSuggest();
@@ -1147,9 +1148,6 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
suggestion_selection::RemoveProfilesNotUsedSinceTimestamp(
min_last_used, &sorted_profiles);
}
- // We need the updated information on the validity states of the profiles.
- UpdateProfilesServerValidityMapsIfNeeded(sorted_profiles);
- MaybeRemoveInvalidSuggestions(type, &sorted_profiles);
}
std::vector<AutofillProfile*> matched_profiles;
@@ -1161,19 +1159,21 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
// Don't show two suggestions if one is a subset of the other.
std::vector<AutofillProfile*> unique_matched_profiles;
std::vector<Suggestion> unique_suggestions =
- suggestion_selection::GetUniqueSuggestions(other_field_types, app_locale_,
+ suggestion_selection::GetUniqueSuggestions(field_types, app_locale_,
matched_profiles, suggestions,
&unique_matched_profiles);
// Generate disambiguating labels based on the list of matches.
std::vector<base::string16> labels;
- AutofillProfile::CreateInferredLabels(
- unique_matched_profiles, &other_field_types, type.GetStorableType(), 1,
- app_locale_, &labels);
+ AutofillProfile::CreateInferredLabels(unique_matched_profiles, &field_types,
+ type.GetStorableType(), 1, app_locale_,
+ &labels);
DCHECK_EQ(unique_suggestions.size(), labels.size());
for (size_t i = 0; i < labels.size(); i++) {
+ // A suggestion's label has one line of disambiguating information to show
+ // to the user. However, when the two-line suggestion display experiment is
+ // enabled on desktop, label is replaced by additional label.
unique_suggestions[i].label = labels[i];
- // Used when two-line display is enabled.
unique_suggestions[i].additional_label = labels[i];
}
@@ -1212,7 +1212,7 @@ const std::vector<CreditCard*> PersonalDataManager::GetCreditCardsToSuggest(
if (a_is_expired != b->IsExpired(comparison_time))
return !a_is_expired;
- return a->CompareFrecency(b, comparison_time);
+ return a->HasGreaterFrecencyThan(b, comparison_time);
});
return cards_to_suggest;
@@ -1342,7 +1342,7 @@ void PersonalDataManager::ClearProfileNonSettingsOrigins() {
for (AutofillProfile* profile : GetProfiles()) {
if (profile->origin() != kSettingsOrigin && !profile->origin().empty()) {
profile->set_origin(std::string());
- UpdateProfileInDB(*profile);
+ UpdateProfileInDB(*profile, /*enforced=*/true);
}
}
@@ -1386,9 +1386,7 @@ void PersonalDataManager::MoveJapanCityToStreetAddress() {
: street_address + line_separator + city;
profile->SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, street_address);
profile->SetRawInfo(ADDRESS_HOME_CITY, base::string16());
-
- // Make the update.
- UpdateProfileInDB(*profile);
+ UpdateProfileInDB(*profile, /*enforced=*/true);
}
}
@@ -1397,17 +1395,36 @@ void PersonalDataManager::MoveJapanCityToStreetAddress() {
}
void PersonalDataManager::OnValidated(const AutofillProfile* profile) {
- // We always set a value for country validity state.
- DCHECK(profile->GetValidityState(ServerFieldType::ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT) !=
- AutofillProfile::UNVALIDATED);
+ if (!profile)
+ return;
+
+ if (!ProfileChangesAreOnGoing(profile->guid()))
+ return;
// Set the validity states updated, only when the validation has occurred. If
// the rules were not loaded for any reason, don't set the flag.
- if (profile->GetValidityState(ServerFieldType::ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT) !=
- AutofillProfile::UNVALIDATED)
- profile->set_is_client_validity_states_updated(true);
+ bool validity_updated =
+ (profile->GetValidityState(ServerFieldType::ADDRESS_HOME_COUNTRY,
+ AutofillProfile::CLIENT) !=
+ AutofillProfile::UNVALIDATED);
+
+ // For every relevant profile change on the ongoing_profile_changes_, mark the
+ // change to show that the validation is done, and set the validity of the
+ // profile if the validity was updated.
+ for (const auto& change : ongoing_profile_changes_[profile->guid()]) {
+ if (!profile->EqualsForClientValidationPurpose(*(change.profile())))
+ continue;
+
+ change.validation_effort_made();
+
+ if (validity_updated) {
+ change.profile()->set_is_client_validity_states_updated(true);
+ change.profile()->SetClientValidityFromBitfieldValue(
+ profile->GetClientValidityBitfieldValue());
+ }
+ }
+
+ HandleNextProfileChange(profile->guid());
}
const ProfileValidityMap& PersonalDataManager::GetProfileValidityByGUID(
@@ -1450,7 +1467,7 @@ std::string PersonalDataManager::MergeProfile(
const std::unique_ptr<AutofillProfile>& b) {
if (a->IsVerified() != b->IsVerified())
return !a->IsVerified();
- return a->CompareFrecency(b.get(), comparison_time);
+ return a->HasGreaterFrecencyThan(b.get(), comparison_time);
});
// Set to true if |existing_profiles| already contains an equivalent profile.
@@ -1954,10 +1971,8 @@ void PersonalDataManager::OnAutofillProfileChanged(
const AutofillProfileDeepChange& change) {
const auto& guid = change.key();
const auto& change_type = change.type();
- const auto& profile = change.profile();
-
+ const auto& profile = *(change.profile());
DCHECK(guid == profile.guid());
-
// Happens only in tests.
if (!ProfileChangesAreOnGoing(guid)) {
DVLOG(1) << "Received an unexpected response from database.";
@@ -1976,7 +1991,8 @@ void PersonalDataManager::OnAutofillProfileChanged(
case AutofillProfileChange::UPDATE:
profiles_server_validities_need_update_ = true;
if (profile_exists &&
- !existing_profile->EqualsForUpdatePurposes(profile)) {
+ (change.enforce_update() ||
+ !existing_profile->EqualsForUpdatePurposes(profile))) {
web_profiles_.erase(
FindElementByGUID<AutofillProfile>(web_profiles_, guid));
web_profiles_.push_back(std::make_unique<AutofillProfile>(profile));
@@ -2034,7 +2050,7 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
Suggestion* suggestion = &suggestions.back();
suggestion->value = credit_card->GetInfo(type, app_locale_);
- suggestion->icon = base::UTF8ToUTF16(credit_card->network());
+ suggestion->icon = credit_card->network();
suggestion->backend_id = credit_card->guid();
suggestion->match = prefix_matched_suggestion
? Suggestion::PREFIX_MATCH
@@ -2063,7 +2079,7 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
suggestion->label = credit_card->NetworkOrBankNameAndLastFourDigits();
#else
suggestion->label = credit_card->ObfuscatedLastFourDigits();
- // Ad the card number with expiry information in the additional
+ // Add the card number with expiry information in the additional
// label portion so that we an show it when two-line display is
// enabled.
suggestion->additional_label =
@@ -2177,7 +2193,7 @@ void PersonalDataManager::DedupeProfiles(
const std::unique_ptr<AutofillProfile>& b) {
if (a->IsVerified() != b->IsVerified())
return !a->IsVerified();
- return a->CompareFrecency(b.get(), comparison_time);
+ return a->HasGreaterFrecencyThan(b.get(), comparison_time);
});
AutofillProfileComparator comparator(app_locale_);
@@ -2321,9 +2337,6 @@ void PersonalDataManager::ConvertWalletAddressesAndUpdateWalletCards() {
UpdateCardsBillingAddressReference(guids_merge_map);
// Force a reload of the profiles and cards.
- // TODO(crbug.com/915229): Remove once the investigation is over.
- if (has_converted_addresses)
- DLOG(WARNING) << this << " conversion of addresses done";
}
}
@@ -2334,11 +2347,6 @@ bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
// If the full Sync feature isn't enabled, then do NOT convert any Wallet
// addresses to local ones.
if (!IsSyncFeatureEnabled()) {
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this
- << " not converting as sync feature is not enabled, probably "
- "due to sync_service_ being "
- << sync_service_;
return false;
}
@@ -2352,12 +2360,9 @@ bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
if (!wallet_address->has_converted()) {
// Try to merge the server address into a similar local profile, or create
// a new local profile if no similar profile is found.
- // TODO(crbug.com/864519): Use GetAccountInfoForPaymentsServer instead of
- // going to IdentityManager directly. This will be necessary to properly
- // support Wallet addresses with Butter.
std::string address_guid = MergeServerAddressesIntoProfiles(
*wallet_address, local_profiles, app_locale_,
- identity_manager_->GetPrimaryAccountInfo().email);
+ GetAccountInfoForPaymentsServer().email);
// Update the map to transfer the billing address relationship from the
// server address to the converted/merged local profile.
@@ -2365,8 +2370,6 @@ bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
// Update the wallet addresses metadata to record the conversion.
wallet_address->set_has_converted(true);
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " converting address " << *wallet_address;
database_helper_->GetServerDatabase()->UpdateServerAddressMetadata(
*wallet_address);
@@ -2541,6 +2544,9 @@ bool PersonalDataManager::DeleteDisusedAddresses() {
}
void PersonalDataManager::ApplyAddressFixesAndCleanups() {
+ // Validate profiles once per major.
+ UpdateClientValidityStates(GetProfiles());
+
// One-time fix, otherwise NOP.
RemoveOrphanAutofillTableRows();
@@ -2579,7 +2585,6 @@ void PersonalDataManager::ResetProfileValidity() {
}
void PersonalDataManager::AddProfileToDB(const AutofillProfile& profile) {
- // Add the new profile to the web database.
if (profile.IsEmpty(app_locale_)) {
NotifyPersonalDataChanged();
return;
@@ -2591,26 +2596,30 @@ void PersonalDataManager::AddProfileToDB(const AutofillProfile& profile) {
NotifyPersonalDataChanged();
return;
}
- database_helper_->GetLocalDatabase()->AddAutofillProfile(profile);
}
- ongoing_profile_changes_[profile.guid()].push(
+ ongoing_profile_changes_[profile.guid()].push_back(
AutofillProfileDeepChange(AutofillProfileChange::ADD, profile));
+ UpdateClientValidityStates(profile);
}
-void PersonalDataManager::UpdateProfileInDB(const AutofillProfile& profile) {
- if (!ProfileChangesAreOnGoing(profile.guid())) {
+void PersonalDataManager::UpdateProfileInDB(const AutofillProfile& profile,
+ bool enforced) {
+ // if the update is enforced, don't check if a similar profile already exists
+ // or not. Otherwise, check if updating the profile makes sense.
+ if (!enforced && !ProfileChangesAreOnGoing(profile.guid())) {
const auto* existing_profile = GetProfileByGUID(profile.guid());
bool profile_exists = (existing_profile != nullptr);
- if (profile_exists && !existing_profile->EqualsForUpdatePurposes(profile)) {
- database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
- } else {
+ if (!profile_exists || existing_profile->EqualsForUpdatePurposes(profile)) {
NotifyPersonalDataChanged();
return;
}
}
- ongoing_profile_changes_[profile.guid()].push(
+ ongoing_profile_changes_[profile.guid()].push_back(
AutofillProfileDeepChange(AutofillProfileChange::UPDATE, profile));
+ if (enforced)
+ ongoing_profile_changes_[profile.guid()].back().set_enforce_update();
+ UpdateClientValidityStates(profile);
}
void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
@@ -2619,11 +2628,12 @@ void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
NotifyPersonalDataChanged();
return;
}
-
- if (!ProfileChangesAreOnGoing(guid))
+ AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, guid);
+ if (!ProfileChangesAreOnGoing(guid)) {
database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
- ongoing_profile_changes_[guid].push(
- AutofillProfileDeepChange(AutofillProfileChange::REMOVE, guid));
+ change.set_is_ongoing_on_background();
+ }
+ ongoing_profile_changes_[guid].push_back(std::move(change));
}
void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
@@ -2631,10 +2641,13 @@ void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
return;
const auto& change = ongoing_profile_changes_[guid].front();
+ if (change.is_ongoing_on_background())
+ return;
+
const auto& change_type = change.type();
const auto* existing_profile = GetProfileByGUID(guid);
const bool profile_exists = (existing_profile != nullptr);
- const auto& profile = ongoing_profile_changes_[guid].front().profile();
+ const auto& profile = *(ongoing_profile_changes_[guid].front().profile());
DCHECK(guid == profile.guid());
@@ -2644,23 +2657,30 @@ void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
return;
}
database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
+ change.set_is_ongoing_on_background();
return;
}
+ if (!change.has_validation_effort_made())
+ return;
+
if (change_type == AutofillProfileChange::ADD) {
if (profile_exists || FindByContents(web_profiles_, profile)) {
OnProfileChangeDone(guid);
return;
}
database_helper_->GetLocalDatabase()->AddAutofillProfile(profile);
+ change.set_is_ongoing_on_background();
return;
}
- if (!profile_exists || existing_profile->EqualsForUpdatePurposes(profile)) {
+ if (profile_exists && (change.enforce_update() ||
+ !existing_profile->EqualsForUpdatePurposes(profile))) {
+ database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
+ change.set_is_ongoing_on_background();
+ } else {
OnProfileChangeDone(guid);
- return;
}
- database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
}
bool PersonalDataManager::ProfileChangesAreOnGoing(const std::string& guid) {
@@ -2670,7 +2690,7 @@ bool PersonalDataManager::ProfileChangesAreOnGoing(const std::string& guid) {
}
bool PersonalDataManager::ProfileChangesAreOnGoing() {
- for (auto task : ongoing_profile_changes_) {
+ for (const auto& task : ongoing_profile_changes_) {
if (ProfileChangesAreOnGoing(task.first)) {
return true;
}
@@ -2679,7 +2699,7 @@ bool PersonalDataManager::ProfileChangesAreOnGoing() {
}
void PersonalDataManager::OnProfileChangeDone(const std::string& guid) {
- ongoing_profile_changes_[guid].pop();
+ ongoing_profile_changes_[guid].pop_front();
if (!ProfileChangesAreOnGoing()) {
Refresh();
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.h b/chromium/components/autofill/core/browser/personal_data_manager.h
index 754305dd365..df97465f599 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.h
+++ b/chromium/components/autofill/core/browser/personal_data_manager.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PERSONAL_DATA_MANAGER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PERSONAL_DATA_MANAGER_H_
+#include <deque>
#include <list>
#include <memory>
#include <set>
@@ -36,9 +37,9 @@
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_member.h"
#include "components/signin/core/browser/account_info.h"
-#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/sync/driver/sync_service_observer.h"
#include "components/webdata/common/web_data_service_consumer.h"
+#include "services/identity/public/cpp/identity_manager.h"
class Browser;
class PrefService;
@@ -56,10 +57,6 @@ void SetProfiles(int, std::vector<autofill::AutofillProfile>*);
void SetCreditCards(int, std::vector<autofill::CreditCard>*);
} // namespace autofill_helper
-namespace identity {
-class IdentityManager;
-}
-
namespace syncer {
class SyncService;
} // namespace syncer
@@ -74,7 +71,7 @@ class PersonalDataManager : public KeyedService,
public AutofillWebDataServiceObserverOnUISequence,
public history::HistoryServiceObserver,
public syncer::SyncServiceObserver,
- public GaiaCookieManagerService::Observer,
+ public identity::IdentityManager::Observer,
public AccountInfoGetter {
public:
explicit PersonalDataManager(const std::string& app_locale);
@@ -95,7 +92,6 @@ class PersonalDataManager : public KeyedService,
identity::IdentityManager* identity_manager,
AutofillProfileValidator* client_profile_validator,
history::HistoryService* history_service,
- GaiaCookieManagerService* cookie_manager_service,
bool is_off_the_record);
// KeyedService:
@@ -123,14 +119,14 @@ class PersonalDataManager : public KeyedService,
void OnSyncShutdown(syncer::SyncService* sync) override;
// AccountInfoGetter:
- AccountInfo GetAccountInfoForPaymentsServer() const override;
+ CoreAccountInfo GetAccountInfoForPaymentsServer() const override;
bool IsSyncFeatureEnabled() const override;
- // GaiaCookieManagerService::Observer:
- void OnGaiaCookieDeletedByUserAction() override;
+ // identity::IdentityManager::Observer:
+ void OnAccountsCookieDeletedByUserAction() override;
// Returns the current sync status.
- AutofillSyncSigninState GetSyncSigninState() const;
+ virtual AutofillSyncSigninState GetSyncSigninState() const;
// Adds a listener to be notified of PersonalDataManager events.
virtual void AddObserver(PersonalDataManagerObserver* observer);
@@ -167,8 +163,7 @@ class PersonalDataManager : public KeyedService,
virtual void RemoveByGUID(const std::string& guid);
// Returns the profile with the specified |guid|, or nullptr if there is no
- // profile with the specified |guid|. Both web and auxiliary profiles may
- // be returned.
+ // profile with the specified |guid|.
virtual AutofillProfile* GetProfileByGUID(const std::string& guid);
// Returns the profile with the specified |guid| from the given |profiles|, or
@@ -255,11 +250,16 @@ class PersonalDataManager : public KeyedService,
void UpdateProfilesServerValidityMapsIfNeeded(
const std::vector<AutofillProfile*>& profiles);
- // Updates the validity states of |profiles| according to client side
- // validation API: |client_profile_validator_|.
+ // Requests an update for the validity states of the |profiles| according to
+ // client side validation API: |client_profile_validator_|.
void UpdateClientValidityStates(
const std::vector<AutofillProfile*>& profiles);
+ // Requests an update for the validity states of the |profile| according to
+ // the client side validation API: |client_profile_validator_|. Returns true
+ // if the validation was requested.
+ bool UpdateClientValidityStates(const AutofillProfile& profile);
+
// Returns the profiles to suggest to the user, ordered by frecency.
std::vector<AutofillProfile*> GetProfilesToSuggest() const;
@@ -269,15 +269,16 @@ class PersonalDataManager : public KeyedService,
const AutofillType& type,
std::vector<AutofillProfile*>* profiles);
- // Loads profiles that can suggest data for |type|. |field_contents| is the
- // part the user has already typed. |field_is_autofilled| is true if the field
- // has already been autofilled. |other_field_types| represents the rest of
- // form.
+ // Returns Suggestions corresponding to the focused field's |type| and
+ // |field_contents|, i.e. what the user has typed. |field_is_autofilled| is
+ // true if the field has already been autofilled, and |field_types| stores the
+ // types of all the form's input fields, including the field with which the
+ // user is interacting.
std::vector<Suggestion> GetProfileSuggestions(
const AutofillType& type,
const base::string16& field_contents,
bool field_is_autofilled,
- const std::vector<ServerFieldType>& other_field_types);
+ const std::vector<ServerFieldType>& field_types);
// Tries to delete disused addresses once per major version if the
// feature is enabled.
@@ -385,8 +386,10 @@ class PersonalDataManager : public KeyedService,
// Records the sync transport consent if the user is in sync transport mode.
virtual void OnUserAcceptedUpstreamOffer();
- // Triggered when a profile is added/updated/removed on db.
- void OnAutofillProfileChanged(const AutofillProfileDeepChange& change);
+ void set_client_profile_validator_for_test(
+ AutofillProfileValidator* validator) {
+ client_profile_validator_ = validator;
+ }
protected:
// Only PersonalDataManagerFactory and certain tests can create instances of
@@ -396,8 +399,6 @@ class PersonalDataManager : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
AddCreditCard_CrazyCharacters);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, AddCreditCard_Invalid);
- FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, FirstMiddleLast);
- FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AutofillIsEnabledAtStartup);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
DedupeProfiles_ProfilesToDelete);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
@@ -442,8 +443,6 @@ class PersonalDataManager : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
DoNotConvertWalletAddressesInEphemeralStorage);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
- DeleteDisusedCreditCards_OncePerVersion);
- FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
DeleteDisusedCreditCards_DoNothingWhenDisabled);
FRIEND_TEST_ALL_PREFIXES(
PersonalDataManagerTest,
@@ -467,9 +466,10 @@ class PersonalDataManager : public KeyedService,
ClearCreditCardNonSettingsOrigins);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
MoveJapanCityToStreetAddress);
- FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, RequestProfileValidity);
FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
- GetProfileSuggestions_InvalidDataBasedOnServer);
+ RequestProfileServerValidity);
+ FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
+ GetProfileSuggestions_Validity);
friend class autofill::AutofillInteractiveTest;
friend class autofill::PersonalDataManagerFactory;
@@ -477,6 +477,8 @@ class PersonalDataManager : public KeyedService,
friend class FormDataImporterTest;
friend class PersonalDataManagerTest;
friend class PersonalDataManagerTestBase;
+ friend class PersonalDataManagerHelper;
+ friend class PersonalDataManagerMockTest;
friend class SaveImportedProfileTest;
friend class ProfileSyncServiceAutofillTest;
friend class ::RemoveAutofillTester;
@@ -561,7 +563,8 @@ class PersonalDataManager : public KeyedService,
// https://crbug.com/871301
void MoveJapanCityToStreetAddress();
- // Called when the |profile| is validated by the AutofillProfileValidator.
+ // Called when the |profile| is validated by the AutofillProfileValidator,
+ // updates the profiles on the |ongoing_profile_changes_| and the DB.
virtual void OnValidated(const AutofillProfile* profile);
// Get the profiles fields validity map by |guid|.
@@ -578,15 +581,11 @@ class PersonalDataManager : public KeyedService,
std::vector<std::unique_ptr<AutofillProfile>> web_profiles_;
// Profiles read from the user's account stored on the server.
- mutable std::vector<std::unique_ptr<AutofillProfile>> server_profiles_;
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles_;
// Stores the PaymentsCustomerData obtained from the database.
std::unique_ptr<PaymentsCustomerData> payments_customer_data_;
- // Storage for web profiles. Contents are weak references. Lifetime managed
- // by |web_profiles_|.
- mutable std::vector<AutofillProfile*> profiles_;
-
// Cached versions of the local and server credit cards.
std::vector<std::unique_ptr<CreditCard>> local_credit_cards_;
std::vector<std::unique_ptr<CreditCard>> server_credit_cards_;
@@ -722,11 +721,16 @@ class PersonalDataManager : public KeyedService,
// Resets |synced_profile_validity_|.
void ResetProfileValidity();
- // Add/Update/Remove profiles on DB.
+ // Add/Update/Remove |profile| on DB.
void AddProfileToDB(const AutofillProfile& profile);
- void UpdateProfileInDB(const AutofillProfile& profile);
+ // |enforced| is true when the update should happen regardless of an equal
+ // profile. (equal in the sense of AutofillProfile::EqualForUpdate)
+ void UpdateProfileInDB(const AutofillProfile& profile, bool enforced = false);
void RemoveProfileFromDB(const std::string& guid);
+ // Triggered when a profile is added/updated/removed on db.
+ void OnAutofillProfileChanged(const AutofillProfileDeepChange& change);
+
// Look at the next profile change for profile with guid = |guid|, and handle
// it.
void HandleNextProfileChange(const std::string& guid);
@@ -754,21 +758,16 @@ class PersonalDataManager : public KeyedService,
// remove itself from the history service's observer list on shutdown.
history::HistoryService* history_service_ = nullptr;
- // The GaiaCookieManagerService to be observed by the personal data manager.
- // Must outlive this instance. This unowned pointer is retained so the PDM can
- // remove itself from the cookie manager service's observer list on shutdown.
- GaiaCookieManagerService* cookie_manager_service_ = nullptr;
-
// Pref registrar for managing the change observers.
PrefChangeRegistrar pref_registrar_;
// Profiles validity read from the prefs. They are kept updated by
// observing changes in pref_services. We need to set the
- // |profile_validities_need_update| whenever this is changed.
+ // |profile_validities_need_update_| whenever this is changed.
std::unique_ptr<UserProfileValidityMap> synced_profile_validity_;
// A timely ordered list of on going changes for each profile.
- std::unordered_map<std::string, std::queue<AutofillProfileDeepChange>>
+ std::unordered_map<std::string, std::deque<AutofillProfileDeepChange>>
ongoing_profile_changes_;
// The client side profile validator.
diff --git a/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc b/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
index f06c16f345b..20fb473789c 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -60,12 +60,16 @@
#include "components/webdata/common/web_database_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/identity_test_environment.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace {
+const char kPrimaryAccountEmail[] = "syncuser@example.com";
+const char kSyncTransportAccountEmail[] = "transport@example.com";
+
enum UserMode { USER_MODE_NORMAL, USER_MODE_INCOGNITO };
const base::Time kArbitraryTime = base::Time::FromDoubleT(25);
@@ -132,7 +136,8 @@ void ExpectSameElements(const std::vector<T*>& expectations,
class PersonalDataManagerTestBase {
protected:
- PersonalDataManagerTestBase() {
+ PersonalDataManagerTestBase()
+ : identity_test_env_(&test_url_loader_factory_) {
// Enable account storage by default, some tests will override this to be
// false.
scoped_features_.InitWithFeatures(
@@ -176,13 +181,6 @@ class PersonalDataManagerTestBase {
account_database_service_->Init();
test::DisableSystemServices(prefs_.get());
- ResetPersonalDataManager(USER_MODE_NORMAL);
-
- // Reset the deduping and profile validation prefs to their default value.
- personal_data_->pref_service_->SetInteger(
- prefs::kAutofillLastVersionDeduped, 0);
- personal_data_->pref_service_->SetInteger(
- prefs::kAutofillLastVersionValidated, CHROME_VERSION_MAJOR);
}
void TearDownTest() {
@@ -193,11 +191,11 @@ class PersonalDataManagerTestBase {
}
void ResetPersonalDataManager(UserMode user_mode,
- bool use_sync_transport_mode) {
+ bool use_sync_transport_mode,
+ PersonalDataManager* personal_data) {
bool is_incognito = (user_mode == USER_MODE_INCOGNITO);
- personal_data_.reset(new PersonalDataManagerMock("en"));
- personal_data_->Init(
+ personal_data->Init(
scoped_refptr<AutofillWebDataService>(profile_database_service_),
base::FeatureList::IsEnabled(
features::kAutofillEnableAccountWalletStorage)
@@ -205,44 +203,147 @@ class PersonalDataManagerTestBase {
: nullptr,
prefs_.get(), identity_test_env_.identity_manager(),
TestAutofillProfileValidator::GetInstance(),
- /*history_service=*/nullptr, /*cookie_manager_sevice=*/nullptr,
- is_incognito);
+ /*history_service=*/nullptr, is_incognito);
- personal_data_->AddObserver(&personal_data_observer_);
+ personal_data->AddObserver(&personal_data_observer_);
AccountInfo account_info;
- account_info.email = "sync@account";
+ account_info.email = use_sync_transport_mode ? kSyncTransportAccountEmail
+ : kPrimaryAccountEmail;
sync_service_.SetAuthenticatedAccountInfo(account_info);
sync_service_.SetIsAuthenticatedAccountPrimary(!use_sync_transport_mode);
- personal_data_->OnSyncServiceInitialized(&sync_service_);
- personal_data_->OnStateChanged(&sync_service_);
+ personal_data->OnSyncServiceInitialized(&sync_service_);
+ personal_data->OnStateChanged(&sync_service_);
WaitForOnPersonalDataChangedRepeatedly();
}
- void ResetPersonalDataManager(UserMode user_mode) {
- ResetPersonalDataManager(user_mode, /*use_sync_transport_mode=*/false);
- }
-
- void ResetProfiles() {
- std::vector<AutofillProfile> empty_profiles;
- personal_data_->SetProfiles(&empty_profiles);
- WaitForOnPersonalDataChanged();
- }
-
- bool TurnOnSyncFeature() WARN_UNUSED_RESULT {
+ bool TurnOnSyncFeature(PersonalDataManager* personal_data)
+ WARN_UNUSED_RESULT {
sync_service_.SetIsAuthenticatedAccountPrimary(true);
if (!sync_service_.IsSyncFeatureEnabled())
return false;
- personal_data_->OnStateChanged(&sync_service_);
- return personal_data_->IsSyncFeatureEnabled();
+ personal_data->OnStateChanged(&sync_service_);
+
+ return personal_data->IsSyncFeatureEnabled();
}
void EnableWalletCardImport() {
- identity_test_env_.MakePrimaryAccountAvailable("syncuser@example.com");
+ identity_test_env_.MakePrimaryAccountAvailable(kPrimaryAccountEmail);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableOfferStoreUnmaskedWalletCards);
}
+ void RemoveByGUIDFromPersonalDataManager(const std::string& guid,
+ PersonalDataManager* personal_data) {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillOnce(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+
+ personal_data->RemoveByGUID(guid);
+ run_loop.Run();
+ }
+
+ void SetServerCards(std::vector<CreditCard> server_cards) {
+ test::SetServerCreditCards(account_autofill_table_, server_cards);
+ }
+
+ // Verify that the web database has been updated and the notification sent.
+ void WaitOnceForOnPersonalDataChanged() {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillOnce(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ run_loop.Run();
+ }
+
+ // Verifies that the web database has been updated and the notification sent.
+ void WaitForOnPersonalDataChanged() {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillOnce(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+ run_loop.Run();
+ }
+
+ // Verifies that the web database has been updated and the notification sent.
+ void WaitForOnPersonalDataChangedRepeatedly() {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillRepeatedly(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+ run_loop.Run();
+ }
+
+ AccountInfo SetActiveSecondaryAccount() {
+ AccountInfo account_info;
+ account_info.email = kSyncTransportAccountEmail;
+ account_info.account_id = "account_id";
+ sync_service_.SetAuthenticatedAccountInfo(account_info);
+ sync_service_.SetIsAuthenticatedAccountPrimary(false);
+ return account_info;
+ }
+
+ void MoveJapanCityToStreetAddress(PersonalDataManager* personal_data,
+ int move_times) {
+ base::RunLoop run_loop;
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillRepeatedly(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(move_times);
+ personal_data->MoveJapanCityToStreetAddress();
+ run_loop.Run();
+ }
+
+ // The temporary directory should be deleted at the end to ensure that
+ // files are not used anymore and deletion succeeds.
+ base::ScopedTempDir temp_dir_;
+ base::test::ScopedTaskEnvironment task_environment_{
+ base::test::ScopedTaskEnvironment::MainThreadType::UI};
+ std::unique_ptr<PrefService> prefs_;
+ network::TestURLLoaderFactory test_url_loader_factory_;
+ identity::IdentityTestEnvironment identity_test_env_;
+ syncer::TestSyncService sync_service_;
+ scoped_refptr<AutofillWebDataService> profile_database_service_;
+ scoped_refptr<AutofillWebDataService> account_database_service_;
+ scoped_refptr<WebDatabaseService> profile_web_database_;
+ scoped_refptr<WebDatabaseService> account_web_database_;
+ AutofillTable* profile_autofill_table_; // weak ref
+ AutofillTable* account_autofill_table_; // weak ref
+ PersonalDataLoadedObserverMock personal_data_observer_;
+ base::test::ScopedFeatureList scoped_features_;
+};
+
+class PersonalDataManagerHelper : public PersonalDataManagerTestBase {
+ protected:
+ virtual ~PersonalDataManagerHelper() {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset();
+ }
+
+ void ResetPersonalDataManager(UserMode user_mode,
+ bool use_account_server_storage = false) {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset(new PersonalDataManager("en"));
+ PersonalDataManagerTestBase::ResetPersonalDataManager(
+ user_mode, use_account_server_storage, personal_data_.get());
+ }
+
+ void ResetProfiles() {
+ std::vector<AutofillProfile> empty_profiles;
+ personal_data_->SetProfiles(&empty_profiles);
+ WaitForOnPersonalDataChanged();
+ }
+
+ bool TurnOnSyncFeature() {
+ return PersonalDataManagerTestBase::TurnOnSyncFeature(personal_data_.get());
+ }
+
void EnableAutofillProfileCleanup() {
personal_data_->is_autofill_profile_cleanup_pending_ = true;
}
@@ -400,14 +501,8 @@ class PersonalDataManagerTestBase {
}
void RemoveByGUIDFromPersonalDataManager(const std::string& guid) {
- base::RunLoop run_loop;
- EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
- .WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
- .Times(testing::AnyNumber());
-
- personal_data_->RemoveByGUID(guid);
- run_loop.Run();
+ PersonalDataManagerTestBase::RemoveByGUIDFromPersonalDataManager(
+ guid, personal_data_.get());
}
void SetServerCards(const std::vector<CreditCard>& server_cards) {
@@ -423,7 +518,8 @@ class PersonalDataManagerTestBase {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
personal_data_->SaveImportedProfile(profile);
run_loop.Run();
@@ -433,91 +529,147 @@ class PersonalDataManagerTestBase {
base::RunLoop run_loop;
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
run_loop.Run();
}
- // Verifies that the web database has been updated and the notification sent.
- void WaitForOnPersonalDataChanged() {
+ std::unique_ptr<PersonalDataManager> personal_data_;
+};
+
+class PersonalDataManagerTest : public PersonalDataManagerHelper,
+ public testing::Test {
+ protected:
+ void SetUp() override {
+ SetUpTest();
+ ResetPersonalDataManager(USER_MODE_NORMAL);
+ }
+ void TearDown() override { TearDownTest(); }
+};
+
+class PersonalDataManagerMockTest : public PersonalDataManagerTestBase,
+ public testing::Test {
+ protected:
+ void SetUp() override {
+ SetUpTest();
+ ResetPersonalDataManager(USER_MODE_NORMAL);
+ // Reset the deduping and profile validation prefs to their default value.
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionDeduped, 0);
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionValidated,
+ atoi(version_info::GetVersionNumber().c_str()));
+ personal_data_->is_autofill_profile_cleanup_pending_ = true;
+ }
+
+ void TearDown() override {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset();
+ TearDownTest();
+ }
+
+ void ResetPersonalDataManager(UserMode user_mode) {
+ if (personal_data_)
+ personal_data_->Shutdown();
+ personal_data_.reset(new PersonalDataManagerMock("en"));
+ PersonalDataManagerTestBase::ResetPersonalDataManager(
+ user_mode, /*use_account_server_storage=*/true, personal_data_.get());
+ }
+
+ bool TurnOnSyncFeature() {
+ return PersonalDataManagerTestBase::TurnOnSyncFeature(personal_data_.get());
+ }
+
+ void StopTheDedupeProcess() {
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionDeduped,
+ atoi(version_info::GetVersionNumber().c_str()));
+ }
+
+ void ResetAutofillLastVersionValidated() {
+ ASSERT_TRUE(personal_data_);
+ personal_data_->pref_service_->SetInteger(
+ prefs::kAutofillLastVersionValidated, 0);
+ }
+
+ void AddProfileToPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
+
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(1);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(
+ personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
+
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
+
+ personal_data_->AddProfile(profile);
+
run_loop.Run();
}
- void WaitOnceForOnPersonalDataChanged() {
+ void UpdateProfileOnPersonalDataManager(const AutofillProfile& profile) {
base::RunLoop run_loop;
+
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(1);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(
+ personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
+
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillOnce(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(1);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+ .Times(testing::AnyNumber());
+
+ personal_data_->UpdateProfile(profile);
+
run_loop.Run();
}
- // Verifies that the web database has been updated and the notification sent.
- void WaitForOnPersonalDataChangedRepeatedly() {
+ void RemoveByGUIDFromPersonalDataManager(const std::string& guid) {
+ PersonalDataManagerTestBase::RemoveByGUIDFromPersonalDataManager(
+ guid, personal_data_.get());
+ }
+
+ void UpdateClientValidityStatesOnPersonalDataManager(
+ const std::vector<AutofillProfile*>& profiles) {
+ int num_updates = 0;
+ if (GetLastVersionValidatedUpdate() < CHROME_VERSION_MAJOR) {
+ num_updates = profiles.size();
+ } else {
+ for (auto* profile : profiles) {
+ if (!profile->is_client_validity_states_updated())
+ num_updates++;
+ }
+ }
+
base::RunLoop run_loop;
+
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(num_updates);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(
+ personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
+
EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
.WillRepeatedly(QuitMessageLoop(&run_loop));
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
.Times(testing::AnyNumber());
+ // Validate the profiles through the client validation API.
+ personal_data_->UpdateClientValidityStates(profiles);
run_loop.Run();
}
- void ExpectOnValidated(AutofillProfile* profile) {
- EXPECT_CALL(*personal_data_, OnValidated(profile)).Times(1);
- ON_CALL(*personal_data_, OnValidated(profile))
- .WillByDefault(testing::Invoke(
- personal_data_.get(), &PersonalDataManagerMock::OnValidatedPDM));
- }
-
- void ResetAutofillLastVersionValidated() {
- ASSERT_TRUE(personal_data_);
- personal_data_->pref_service_->SetInteger(
- prefs::kAutofillLastVersionValidated, 0);
- }
-
int GetLastVersionValidatedUpdate() {
return personal_data_->pref_service_->GetInteger(
prefs::kAutofillLastVersionValidated);
}
- AccountInfo SetActiveSecondaryAccount() {
- AccountInfo account_info;
- account_info.email = "signed_in_account@email.com";
- account_info.account_id = "account_id";
- sync_service_.SetAuthenticatedAccountInfo(account_info);
- sync_service_.SetIsAuthenticatedAccountPrimary(false);
- return account_info;
- }
-
- // The temporary directory should be deleted at the end to ensure that
- // files are not used anymore and deletion succeeds.
- base::ScopedTempDir temp_dir_;
- base::test::ScopedTaskEnvironment task_environment_{
- base::test::ScopedTaskEnvironment::MainThreadType::UI};
- std::unique_ptr<PrefService> prefs_;
- identity::IdentityTestEnvironment identity_test_env_;
- syncer::TestSyncService sync_service_;
- scoped_refptr<AutofillWebDataService> profile_database_service_;
- scoped_refptr<AutofillWebDataService> account_database_service_;
- scoped_refptr<WebDatabaseService> profile_web_database_;
- scoped_refptr<WebDatabaseService> account_web_database_;
- AutofillTable* profile_autofill_table_ = nullptr; // weak ref
- AutofillTable* account_autofill_table_ = nullptr; // weak ref
- PersonalDataLoadedObserverMock personal_data_observer_;
std::unique_ptr<PersonalDataManagerMock> personal_data_;
- base::test::ScopedFeatureList scoped_features_;
-};
-
-class PersonalDataManagerTest : public PersonalDataManagerTestBase,
- public testing::Test {
- void SetUp() override { SetUpTest(); }
-
- void TearDown() override { TearDownTest(); }
};
TEST_F(PersonalDataManagerTest, AddProfile) {
@@ -572,6 +724,7 @@ TEST_F(PersonalDataManagerTest, AddRemoveUpdateProfileSequence) {
personal_data_->AddProfile(profile);
personal_data_->RemoveByGUID(profile.guid());
+ personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
auto profiles = personal_data_->GetProfiles();
@@ -581,20 +734,54 @@ TEST_F(PersonalDataManagerTest, AddRemoveUpdateProfileSequence) {
personal_data_->RemoveByGUID(profile.guid());
personal_data_->RemoveByGUID(profile.guid());
WaitForOnPersonalDataChanged();
+
profiles = personal_data_->GetProfiles();
ASSERT_EQ(0U, profiles.size());
personal_data_->AddProfile(profile);
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
personal_data_->UpdateProfile(profile);
+ WaitForOnPersonalDataChanged();
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
+ base::ASCIIToUTF16("new@email.com"));
+
profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("newer@email.com"));
personal_data_->UpdateProfile(profile);
+ profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("newest@email.com"));
+ personal_data_->UpdateProfile(profile);
WaitForOnPersonalDataChanged();
profiles = personal_data_->GetProfiles();
ASSERT_EQ(1U, profiles.size());
EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
- base::ASCIIToUTF16("newer@email.com"));
+ base::ASCIIToUTF16("newest@email.com"));
+}
+
+// The changes should happen in the same order as requested. If the later change
+// is validated before an earlier one, still we should process the earlier one
+// first.
+TEST_F(PersonalDataManagerTest, InconsistentValidationSequence) {
+ auto profile = test::GetFullProfile();
+ // Slow validation.
+ personal_data_->set_client_profile_validator_for_test(
+ TestAutofillProfileValidator::GetDelayedInstance());
+ personal_data_->AddProfile(profile);
+
+ // No validator, zero delay for validation.
+ personal_data_->set_client_profile_validator_for_test(nullptr);
+ profile.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("new@email.com"));
+ personal_data_->UpdateProfile(profile);
+
+ WaitForOnPersonalDataChanged();
+
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(profiles[0]->GetRawInfo(EMAIL_ADDRESS),
+ base::ASCIIToUTF16("new@email.com"));
+ EXPECT_FALSE(profiles[0]->is_client_validity_states_updated());
}
// Test that a new profile has its basic information set.
@@ -1453,7 +1640,6 @@ TEST_F(PersonalDataManagerTest, SaveImportedProfileWithVerifiedData) {
"Hollywood", "CA", "91601", "US", "12345678910");
EXPECT_FALSE(profile.IsVerified());
- // Add the profile to the database.
AddProfileToPersonalDataManager(profile);
// Make sure everything is set up correctly.
@@ -2104,66 +2290,57 @@ TEST_F(PersonalDataManagerTest,
}
// Tests that suggestions based on invalid data are handled correctly.
-TEST_F(PersonalDataManagerTest,
- GetProfileSuggestions_InvalidDataBasedOnClient) {
- // Set up 2 different profiles.
- AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "123 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "CA", "91601", "US", "9876543210");
- profile1.SetValidityState(PHONE_HOME_WHOLE_NUMBER, AutofillProfile::INVALID,
- AutofillProfile::CLIENT);
- profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
- AddProfileToPersonalDataManager(profile1);
+TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
+ // Set up 2 different profiles: one valid and one invalid.
+ AutofillProfile valid_profile(test::GetFullValidProfileForCanada());
+ valid_profile.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(200));
+ valid_profile.set_use_count(1);
+ AddProfileToPersonalDataManager(valid_profile);
- AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "456 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "CA", "91601", "US", "1234567890");
- AddProfileToPersonalDataManager(profile2);
+ AutofillProfile invalid_profile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&invalid_profile, "Marion1", "Mitchell", "Morrison",
+ "invalid email", "Fox",
+ "123 Zoo St.\nSecond Line\nThird line", "unit 5",
+ "Hollywood", "CA", "91601", "US", "Invalid Phone");
+ invalid_profile.set_use_date(AutofillClock::Now());
+ invalid_profile.set_use_count(1000);
+ AddProfileToPersonalDataManager(invalid_profile);
- ResetPersonalDataManager(USER_MODE_NORMAL);
- {
- base::HistogramTester histogram_tester;
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(PHONE_HOME_WHOLE_NUMBER), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(1U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("1234567890"), suggestions[0].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", false, 1);
- }
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
+ // Invalid based on client, and not invalid by server. Relying on both
+ // validity sources.
{
- base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(PHONE_HOME_WHOLE_NUMBER), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(2U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("1234567890"), suggestions[0].value);
- EXPECT_EQ(base::ASCIIToUTF16("9876543210"), suggestions[1].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", true, 1);
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses});
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_TRUE(profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
-}
-// Tests that suggestions based on invalid data are handled correctly.
-TEST_F(PersonalDataManagerTest,
- GetProfileSuggestions_InvalidDataBasedOnServer) {
- // Set up 2 different profiles.
- AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "123 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "CA", "91601", "US", "9876543210");
// Set the validity state of ADDRESS_HOME_STATE to INVALID on the prefs.
{
ProfileValidityMap profile_validity_map;
@@ -2171,9 +2348,11 @@ TEST_F(PersonalDataManagerTest,
std::string autofill_profile_validity;
personal_data_->pref_service_->SetString(prefs::kAutofillProfileValidity,
autofill_profile_validity);
- (*profile_validity_map.mutable_field_validity_states())[static_cast<int>(
- ADDRESS_HOME_STATE)] = static_cast<int>(AutofillProfile::INVALID);
- (*user_profile_validity_map.mutable_profile_validity())[profile1.guid()] =
+ (*profile_validity_map
+ .mutable_field_validity_states())[static_cast<int>(EMAIL_ADDRESS)] =
+ static_cast<int>(AutofillProfile::INVALID);
+ (*user_profile_validity_map
+ .mutable_profile_validity())[invalid_profile.guid()] =
profile_validity_map;
ASSERT_TRUE(user_profile_validity_map.SerializeToString(
&autofill_profile_validity));
@@ -2181,44 +2360,98 @@ TEST_F(PersonalDataManagerTest,
personal_data_->pref_service_->SetString(prefs::kAutofillProfileValidity,
autofill_profile_validity);
}
- profile1.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(20));
- AddProfileToPersonalDataManager(profile1);
-
- AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
- test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
- "johnwayne@me.xyz", "Fox",
- "456 Zoo St.\nSecond Line\nThird line", "unit 5",
- "Hollywood", "NY", "91601", "US", "1234567890");
- AddProfileToPersonalDataManager(profile2);
-
- ResetPersonalDataManager(USER_MODE_NORMAL);
+ // Invalid based on client, and server. Relying on both validity sources.
{
- base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(ADDRESS_HOME_STATE), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(1U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("NY"), suggestions[0].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", false, 1);
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation,
+ features::kAutofillProfileServerValidation},
+ /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses});
+
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
-
+ // Invalid based on client, and server. Relying only on the client source.
{
- base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillSuggestInvalidProfileData);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(ADDRESS_HOME_STATE), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(2U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("CA"), suggestions[1].value);
- EXPECT_EQ(base::ASCIIToUTF16("NY"), suggestions[0].value);
- histogram_tester.ExpectUniqueSample(
- "Autofill.InvalidProfileData.UsedForSuggestion", true, 1);
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses,
+ features::kAutofillProfileServerValidation});
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
+ }
+ // Invalid based on client, and server. Relying on server as a validity
+ // source.
+ {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation},
+ /*disabled_features=*/{features::kAutofillProfileClientValidation,
+ features::kAutofillSuppressDisusedAddresses});
+ LOG(ERROR) << __FUNCTION__;
+ std::vector<Suggestion> email_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+
+ for (auto* profile : profiles) {
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByClient());
+ ASSERT_EQ(profile->guid() == valid_profile.guid(),
+ profile->IsValidByServer());
+ }
+ ASSERT_EQ(1U, email_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("alice@wonderland.ca"),
+ email_suggestions[0].value);
+
+ std::vector<Suggestion> name_suggestions =
+ personal_data_->GetProfileSuggestions(AutofillType(NAME_FIRST),
+ base::string16(), false,
+ std::vector<ServerFieldType>());
+ ASSERT_EQ(2U, name_suggestions.size());
+ EXPECT_EQ(base::ASCIIToUTF16("Alice"), name_suggestions[0].value);
+ EXPECT_EQ(base::ASCIIToUTF16("Marion1"), name_suggestions[1].value);
}
}
@@ -2995,16 +3228,6 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
base::TimeDelta::FromDays(15));
server_cards.back().SetNetworkForMaskedCard(kVisaCard);
- // This server card is identical to a local card, but has a different
- // card type. Not a dupe and therefore both should appear in the suggestions.
- server_cards.push_back(CreditCard(CreditCard::MASKED_SERVER_CARD, "b456"));
- test::SetCreditCardInfo(&server_cards.back(), "Bonnie Parker", "5100", "12",
- "2999", "1");
- server_cards.back().set_use_count(3);
- server_cards.back().set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(15));
- server_cards.back().SetNetworkForMaskedCard(kVisaCard);
-
// This unmasked server card is an exact dupe of a local card. Therefore only
// this card should appear in the suggestions as full server cards have
// precedence over local cards.
@@ -3021,23 +3244,22 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
// Make sure everything is set up correctly.
personal_data_->Refresh();
WaitForOnPersonalDataChanged();
- EXPECT_EQ(6U, personal_data_->GetCreditCards().size());
+ EXPECT_EQ(5U, personal_data_->GetCreditCards().size());
std::vector<Suggestion> suggestions =
personal_data_->GetCreditCardSuggestions(
AutofillType(CREDIT_CARD_NAME_FULL),
/* field_contents= */ base::string16(),
/*include_server_cards=*/true);
- ASSERT_EQ(4U, suggestions.size());
+ ASSERT_EQ(3U, suggestions.size());
EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[0].value);
EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[2].value);
- EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[3].value);
suggestions = personal_data_->GetCreditCardSuggestions(
AutofillType(CREDIT_CARD_NUMBER), /* field_contents= */ base::string16(),
/*include_server_cards=*/true);
- ASSERT_EQ(4U, suggestions.size());
+ ASSERT_EQ(3U, suggestions.size());
EXPECT_EQ(base::UTF8ToUTF16(std::string("Visa ") +
test::ObfuscatedCardDigitsAsUTF8("3456")),
suggestions[0].value);
@@ -3047,9 +3269,6 @@ TEST_F(PersonalDataManagerTest, GetCreditCardSuggestions_ServerDuplicates) {
EXPECT_EQ(base::UTF8ToUTF16(std::string("Mastercard ") +
test::ObfuscatedCardDigitsAsUTF8("5100")),
suggestions[2].value);
- EXPECT_EQ(base::UTF8ToUTF16(std::string("Visa ") +
- test::ObfuscatedCardDigitsAsUTF8("5100")),
- suggestions[3].value);
}
// Tests that a full server card can be a dupe of more than one local card.
@@ -3249,40 +3468,39 @@ TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_FullServerAndMasked) {
EXPECT_EQ(2U, credit_cards.size());
}
-// Tests that slightly different local, full server, and masked credit cards are
-// not deduped.
+// Tests that different local, masked, and full server credit cards are not
+// deduped.
TEST_F(PersonalDataManagerTest, DedupeCreditCardToSuggest_DifferentCards) {
std::list<CreditCard*> credit_cards;
- CreditCard credit_card2("002149C1-EE28-4213-A3B9-DA243FFF021B",
- test::kEmptyOrigin);
- credit_card2.set_use_count(1);
- credit_card2.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(1));
- test::SetCreditCardInfo(&credit_card2, "Homer Simpson",
+ CreditCard local_card("002149C1-EE28-4213-A3B9-DA243FFF021B",
+ test::kEmptyOrigin);
+ local_card.set_use_count(1);
+ local_card.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(1));
+ test::SetCreditCardInfo(&local_card, "Homer Simpson",
"5105105105105100" /* Mastercard */, "", "", "");
- credit_cards.push_back(&credit_card2);
+ credit_cards.push_back(&local_card);
- // Create a masked server card that is slightly different of the local card.
- CreditCard credit_card4(CreditCard::MASKED_SERVER_CARD, "b456");
- test::SetCreditCardInfo(&credit_card4, "Homer Simpson", "5100", "12", "2999",
+ // Create a masked server card that is different from the local card.
+ CreditCard masked_card(CreditCard::MASKED_SERVER_CARD, "b456");
+ test::SetCreditCardInfo(&masked_card, "Homer Simpson", "0005", "12", "2999",
"1");
- credit_card4.set_use_count(3);
- credit_card4.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(15));
- credit_card4.SetNetworkForMaskedCard(kVisaCard);
- credit_cards.push_back(&credit_card4);
+ masked_card.set_use_count(3);
+ masked_card.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(15));
+ // credit_card4.SetNetworkForMaskedCard(kVisaCard);
+ credit_cards.push_back(&masked_card);
// Create a full server card that is slightly different of the two other
// cards.
- CreditCard credit_card5(CreditCard::FULL_SERVER_CARD, "c789");
- test::SetCreditCardInfo(&credit_card5, "Homer Simpson",
+ CreditCard full_server_card(CreditCard::FULL_SERVER_CARD, "c789");
+ test::SetCreditCardInfo(&full_server_card, "Homer Simpson",
"378282246310005" /* American Express */, "04",
"2999", "1");
- credit_card5.set_use_count(1);
- credit_card5.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(15));
- credit_cards.push_back(&credit_card5);
+ full_server_card.set_use_count(1);
+ full_server_card.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(15));
+ credit_cards.push_back(&full_server_card);
PersonalDataManager::DedupeCreditCardToSuggest(&credit_cards);
EXPECT_EQ(3U, credit_cards.size());
@@ -3535,13 +3753,16 @@ typedef struct {
} SaveImportedProfileTestCase;
class SaveImportedProfileTest
- : public PersonalDataManagerTestBase,
+ : public PersonalDataManagerHelper,
public testing::TestWithParam<SaveImportedProfileTestCase> {
public:
SaveImportedProfileTest() {}
~SaveImportedProfileTest() override {}
- void SetUp() override { SetUpTest(); }
+ void SetUp() override {
+ SetUpTest();
+ ResetPersonalDataManager(USER_MODE_NORMAL);
+ }
void TearDown() override { TearDownTest(); }
};
@@ -3605,7 +3826,7 @@ TEST_P(SaveImportedProfileTest, SaveImportedProfile) {
ResetProfiles();
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
PersonalDataManagerTest,
SaveImportedProfileTest,
testing::Values(
@@ -5207,7 +5428,7 @@ TEST_F(PersonalDataManagerTest,
// Make sure that the added address has the email address of the currently
// signed-in user.
- EXPECT_EQ(base::UTF8ToUTF16("syncuser@example.com"),
+ EXPECT_EQ(base::UTF8ToUTF16(kPrimaryAccountEmail),
profiles[0]->GetRawInfo(EMAIL_ADDRESS));
}
@@ -5344,9 +5565,6 @@ TEST_F(PersonalDataManagerTest,
///////////////////////////////////////////////////////////////////////
personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
- ///////////////////////////////////////////////////////////////////////
- // Validation.
- ///////////////////////////////////////////////////////////////////////
// Since there should be no change in data, OnPersonalDataChanged should not
// have been called.
EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
@@ -5418,6 +5636,7 @@ TEST_F(
"2999", "1");
local_card.set_billing_address_id(kServerAddressId);
personal_data_->AddCreditCard(local_card);
+ WaitForOnPersonalDataChanged();
std::vector<CreditCard> server_cards;
server_cards.push_back(
@@ -6213,6 +6432,10 @@ TEST_F(PersonalDataManagerTest, OnSyncServiceInitialized_NotActiveSyncService) {
1);
histogram_tester.ExpectUniqueSample(
"Autofill.ResetFullServerCards.NumberOfCardsReset", 1, 1);
+
+ // Call OnSyncShutdown to ensure removing observer added by
+ // OnSyncServiceInitialized.
+ personal_data_->OnSyncShutdown(&sync_service);
}
#endif // !defined(OS_LINUX) || defined(OS_CHROMEOS)
@@ -6465,6 +6688,9 @@ TEST_F(PersonalDataManagerTest, ClearCreditCardNonSettingsOrigins) {
// Tests that all city fields in a Japan profile are moved to the street address
// field.
TEST_F(PersonalDataManagerTest, MoveJapanCityToStreetAddress) {
+ // Turn on sync feature to avoid calling MoveJapanCityToStreetAddress on
+ // adding the profiles implicitly.
+ ASSERT_TRUE(TurnOnSyncFeature());
// A US profile with both street address and a city.
std::string guid0 = base::GenerateGUID();
{
@@ -6514,14 +6740,12 @@ TEST_F(PersonalDataManagerTest, MoveJapanCityToStreetAddress) {
"JP", "");
AddProfileToPersonalDataManager(profile4);
}
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(5U, profiles.size());
- base::RunLoop run_loop;
- EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
- .WillRepeatedly(QuitMessageLoop(&run_loop));
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
- .Times(2); // For the Japan profiles where the city is not empty.
- personal_data_->MoveJapanCityToStreetAddress();
- run_loop.Run();
+ MoveJapanCityToStreetAddress(
+ personal_data_.get(),
+ 2); // For the japan profiles where the city is not empty.
{
AutofillProfile* profile0 = personal_data_->GetProfileByGUID(guid0);
@@ -6742,9 +6966,9 @@ TEST_F(PersonalDataManagerTest, UseCorrectStorageForDifferentCards) {
EXPECT_EQ(profile, *profiles[0]);
}
-// Requests profiles fields validities: empty profiles, non-existent profiles,
-// and normal ones.
-TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
+// Requests profiles fields validities according to the server: empty profiles,
+// non-existent profiles, and normal ones.
+TEST_F(PersonalDataManagerTest, RequestProfileServerValidity) {
ResetPersonalDataManager(USER_MODE_NORMAL);
ProfileValidityMap profile_validity_map;
@@ -6767,10 +6991,10 @@ TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
std::vector<ServerFieldType> types = {
ADDRESS_HOME_LINE1, ADDRESS_HOME_STATE, ADDRESS_HOME_COUNTRY,
EMAIL_ADDRESS, ADDRESS_HOME_ZIP, NAME_FULL};
- std::vector<AutofillProfile::ValidityState> states = {
- AutofillProfile::UNSUPPORTED, AutofillProfile::EMPTY,
- AutofillProfile::INVALID, AutofillProfile::VALID,
- AutofillProfile::UNVALIDATED, AutofillProfile::INVALID};
+ std::vector<AutofillDataModel::ValidityState> states = {
+ AutofillDataModel::UNSUPPORTED, AutofillDataModel::EMPTY,
+ AutofillDataModel::INVALID, AutofillDataModel::VALID,
+ AutofillDataModel::UNVALIDATED, AutofillDataModel::INVALID};
ASSERT_EQ(types.size(), states.size());
for (unsigned long i = 0; i < types.size(); ++i) {
(*profile_validity_map
@@ -6791,7 +7015,7 @@ TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
autofill_profile_validity.clear();
(*profile_validity_map
.mutable_field_validity_states())[static_cast<int>(EMAIL_ADDRESS)] =
- static_cast<int>(AutofillProfile::VALID);
+ static_cast<int>(AutofillDataModel::VALID);
(*user_profile_validity_map.mutable_profile_validity())[guid] =
profile_validity_map;
ASSERT_TRUE(
@@ -6818,130 +7042,54 @@ TEST_F(PersonalDataManagerTest, RequestProfileValidity) {
validities =
personal_data_->GetProfileValidityByGUID(guid).field_validity_states();
ASSERT_FALSE(validities.empty());
- EXPECT_EQ(validities.at(EMAIL_ADDRESS), AutofillProfile::VALID);
+ EXPECT_EQ(validities.at(EMAIL_ADDRESS), AutofillDataModel::VALID);
}
// Use the client side validation API to validate three PDM profiles. This one
// doesn't test the upload process or saving to the database.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates) {
- // Create three profiles and add them to personal_data_.
- AutofillProfile valid_profile(test::GetFullValidProfileForCanada());
- valid_profile.set_use_date(AutofillClock::Now());
- valid_profile.set_guid("00000000-0000-0000-0000-000000000001");
- AddProfileToPersonalDataManager(valid_profile);
-
- AutofillProfile profile_invalid_phone_email(
- test::GetFullValidProfileForChina());
- profile_invalid_phone_email.SetRawInfo(
- PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16("invalid phone number!"));
- profile_invalid_phone_email.SetRawInfo(EMAIL_ADDRESS,
- base::UTF8ToUTF16("invalid email!"));
- profile_invalid_phone_email.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(10));
- profile_invalid_phone_email.set_guid("00000000-0000-0000-0000-000000000002");
- AddProfileToPersonalDataManager(profile_invalid_phone_email);
-
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates) {
AutofillProfile profile_invalid_province(base::GenerateGUID(),
test::kEmptyOrigin);
test::SetProfileInfo(&profile_invalid_province, "Alice", "", "Munro",
"alice@munro.ca", "Fox", "123 Zoo St", "unit 5",
"Montreal", "CA", "H3C 2A3", "CA", "15142343254");
- profile_invalid_province.set_guid("00000000-0000-0000-0000-000000000003");
- profile_invalid_province.set_use_date(AutofillClock::Now() -
- base::TimeDelta::FromDays(100));
AddProfileToPersonalDataManager(profile_invalid_province);
- ASSERT_EQ(3U, personal_data_->GetProfiles().size());
-
- // Validate the profiles through the client validation API.
+ ASSERT_EQ(1U, personal_data_->GetProfiles().size());
auto profiles = personal_data_->GetProfiles();
- for (auto* profile : profiles) {
- ASSERT_FALSE(profile->is_client_validity_states_updated());
- // Expect OnValidated to be called for each profile.
- ExpectOnValidated(profile);
- }
+ profiles[0]->set_is_client_validity_states_updated(false);
- personal_data_->UpdateClientValidityStates(profiles);
+ UpdateClientValidityStatesOnPersonalDataManager(profiles);
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
- ASSERT_EQ(3U, profiles.size());
- // The profiles are ordered according to their guid.
- // valid_profile:
- ASSERT_EQ(valid_profile.guid(), profiles[0]->guid());
EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profiles[0]->GetValidityState(ADDRESS_HOME_STATE,
AutofillProfile::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
+ AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_CITY,
AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
+ EXPECT_EQ(AutofillDataModel::EMPTY,
profiles[0]->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
AutofillProfile::CLIENT));
EXPECT_EQ(
- AutofillProfile::VALID,
+ AutofillDataModel::VALID,
profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(PHONE_HOME_WHOLE_NUMBER,
AutofillProfile::CLIENT));
-
- // profile_invalid_phone_email:
- ASSERT_EQ(profile_invalid_phone_email.guid(), profiles[1]->guid());
- EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::INVALID,
- profiles[1]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profiles[1]->GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
-
- ASSERT_EQ(profile_invalid_province.guid(), profiles[2]->guid());
- EXPECT_TRUE(profiles[2]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_ZIP, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
- profiles[2]->GetValidityState(ADDRESS_HOME_CITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::EMPTY,
- profiles[2]->GetValidityState(ADDRESS_HOME_DEPENDENT_LOCALITY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(
- AutofillProfile::VALID,
- profiles[2]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[2]->GetValidityState(PHONE_HOME_WHOLE_NUMBER,
- AutofillProfile::CLIENT));
}
// Check the validity update status for AutofillProfiles.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_UpdatedFlag) {
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_UpdatedFlag) {
// Create two profiles and add them to personal_data_.
AutofillProfile profile1(test::GetFullValidProfileForCanada());
AddProfileToPersonalDataManager(profile1);
@@ -6951,18 +7099,10 @@ TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_UpdatedFlag) {
ASSERT_EQ(2U, personal_data_->GetProfiles().size());
- // Validate the profiles through the client validation API.
+ // The validities were set when the profiles were added.
auto profiles = personal_data_->GetProfiles();
- ASSERT_FALSE(profiles[0]->is_client_validity_states_updated());
- ASSERT_FALSE(profiles[1]->is_client_validity_states_updated());
-
- ExpectOnValidated(profiles[0]);
- ExpectOnValidated(profiles[1]);
- personal_data_->UpdateClientValidityStates(profiles);
-
- ASSERT_EQ(2U, profiles.size());
- EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
- EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
+ ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
+ ASSERT_TRUE(profiles[1]->is_client_validity_states_updated());
*profiles[1] = *profiles[0];
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
@@ -6972,118 +7112,189 @@ TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_UpdatedFlag) {
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
ASSERT_FALSE(profiles[1]->is_client_validity_states_updated());
- ExpectOnValidated(profiles[1]);
- personal_data_->UpdateClientValidityStates(profiles);
+ profiles[0]->SetRawInfo(NAME_FULL, base::UTF8ToUTF16("Goli Boli"));
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
- ASSERT_TRUE(profiles[1]->is_client_validity_states_updated());
+}
+
+// Check the validity update status for AutofillProfiles.
+TEST_F(PersonalDataManagerMockTest,
+ UpdateClientValidityStates_UpdatedFlag_Merge) {
+ // Set the pref to the current major version.
+ StopTheDedupeProcess();
+
+ AutofillProfile profile1(test::GetFullValidProfileForCanada());
+ AddProfileToPersonalDataManager(profile1);
+
+ AutofillProfile profile2(test::GetFullValidProfileForCanada());
+ profile2.set_guid("00000000-0000-0000-0000-000000002019");
+ profile2.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, base::UTF8ToUTF16(""));
+ AddProfileToPersonalDataManager(profile2);
+
+ // The validities were set when the profiles were added.
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
profiles[1]->MergeDataFrom(*profiles[0], "en");
ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
ASSERT_FALSE(profiles[1]->is_client_validity_states_updated());
-
- profiles[0]->SetRawInfo(NAME_FULL, base::UTF8ToUTF16("Goli Boli"));
- ASSERT_TRUE(profiles[0]->is_client_validity_states_updated());
}
// Check that the validity states are not updated when the validity flags are up
// to date.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_AlreadyUpdated) {
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_AlreadyUpdated) {
// Create two profiles and add them to personal_data_.
AutofillProfile profile1(test::GetFullValidProfileForCanada());
profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
AddProfileToPersonalDataManager(profile1);
- AutofillProfile profile2(test::GetFullValidProfileForChina());
- profile2.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("invalid state!"));
- AddProfileToPersonalDataManager(profile2);
-
- EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(0);
-
auto profiles = personal_data_->GetProfiles();
- ASSERT_EQ(2U, profiles.size());
+ ASSERT_EQ(1U, profiles.size());
+ // The validities were updated when the profile was added.
+ EXPECT_EQ(
+ AutofillDataModel::INVALID,
+ profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
+
+ // Change the email, the validity update would turn false.
+ profiles[0]->SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("alice@gmail.com"));
+ EXPECT_FALSE(profiles[0]->is_client_validity_states_updated());
// Pretend that the validity states are updated.
profiles[0]->set_is_client_validity_states_updated(true);
- profiles[1]->set_is_client_validity_states_updated(true);
// Validating the profiles through the client validation API should not change
// the validity states.
personal_data_->UpdateClientValidityStates(profiles);
+
profiles = personal_data_->GetProfiles();
- ASSERT_EQ(2U, profiles.size());
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
+ ASSERT_EQ(1U, profiles.size());
EXPECT_EQ(
- AutofillProfile::UNVALIDATED,
+ AutofillDataModel::INVALID,
profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profiles[1]->GetValidityState(ADDRESS_HOME_COUNTRY,
- AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
- profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
+ // Try with the flag as not updated.
+ profiles[0]->set_is_client_validity_states_updated(false);
+
+ UpdateClientValidityStatesOnPersonalDataManager(profiles);
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(
+ AutofillDataModel::VALID,
+ profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
}
// Verify that the fields are validated according to the version.
-TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_Version) {
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_Version) {
// Create two profiles and add them to personal_data_. Set the guids
// explicitly to preserve the order.
- AutofillProfile profile1(test::GetFullValidProfileForCanada());
- profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
- profile1.set_guid("00000000-0000-0000-0000-000000000001");
- AddProfileToPersonalDataManager(profile1);
-
AutofillProfile profile2(test::GetFullValidProfileForChina());
profile2.SetRawInfo(ADDRESS_HOME_STATE, base::UTF8ToUTF16("invalid state!"));
profile2.set_guid("00000000-0000-0000-0000-000000000002");
+ profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(200));
AddProfileToPersonalDataManager(profile2);
+ AutofillProfile profile1(test::GetFullValidProfileForCanada());
+ profile1.SetRawInfo(EMAIL_ADDRESS, base::UTF8ToUTF16("invalid email!"));
+ profile1.set_use_date(AutofillClock::Now());
+ profile1.set_guid("00000000-0000-0000-0000-000000000001");
+ AddProfileToPersonalDataManager(profile1);
+
auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
- // Pretend that the validity states are updated.
- profiles[0]->set_is_client_validity_states_updated(true);
- profiles[1]->set_is_client_validity_states_updated(true);
+ EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
+ EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
+ EXPECT_EQ(CHROME_VERSION_MAJOR, GetLastVersionValidatedUpdate());
- // Should validate regardless of the validity update flag, because of the
- // major version update.
- ResetAutofillLastVersionValidated();
+ // No validation as both validity update flags are true, and the validation
+ // version is set to this version.
+ base::RunLoop run_loop;
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(0);
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
+ personal_data_->UpdateClientValidityStates(profiles);
profiles = personal_data_->GetProfiles();
ASSERT_EQ(2U, profiles.size());
+ ResetAutofillLastVersionValidated();
- ExpectOnValidated(profiles[0]);
- ExpectOnValidated(profiles[1]);
+ EXPECT_EQ(0, GetLastVersionValidatedUpdate());
+ EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
+ EXPECT_TRUE(profiles[1]->is_client_validity_states_updated());
+
+ // Should validate regardless of the validity update flag, because of the
+ // major version update.
+ EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(2);
+ ON_CALL(*personal_data_, OnValidated(testing::_))
+ .WillByDefault(testing::Invoke(personal_data_.get(),
+ &PersonalDataManagerMock::OnValidatedPDM));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+ .WillRepeatedly(QuitMessageLoop(&run_loop));
+ EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(2);
+ // Validate the profiles through the client validation API.
personal_data_->UpdateClientValidityStates(profiles);
+ run_loop.Run();
- EXPECT_EQ(AutofillProfile::VALID,
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(2U, profiles.size());
+ ASSERT_EQ(profiles[0]->guid(), profile1.guid());
+
+ // Verify that the version of the last update is set to this version.
+ EXPECT_EQ(CHROME_VERSION_MAJOR, GetLastVersionValidatedUpdate());
+
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
EXPECT_EQ(
- AutofillProfile::INVALID,
+ AutofillDataModel::INVALID,
profiles[0]->GetValidityState(EMAIL_ADDRESS, AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::VALID,
+ EXPECT_EQ(AutofillDataModel::VALID,
profiles[1]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
- EXPECT_EQ(AutofillProfile::INVALID,
+ EXPECT_EQ(AutofillDataModel::INVALID,
profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
AutofillProfile::CLIENT));
+}
- // Verify that the version of the last update is set to this version.
- EXPECT_EQ(CHROME_VERSION_MAJOR, GetLastVersionValidatedUpdate());
+// Verifies that the profiles are validated when added, updated.
+TEST_F(PersonalDataManagerMockTest, UpdateProfilesValidityStates_AddUpdate) {
+ // Add
+ AutofillProfile profile1(test::GetFullValidProfileForCanada());
+ AddProfileToPersonalDataManager(profile1);
- // Update should not update any validity state, because both the validity
- // state flag and the version are up to date.
- // A fake change in the validity state of profile[1].
- profiles[1]->SetValidityState(ADDRESS_HOME_STATE, AutofillProfile::VALID,
- AutofillProfile::CLIENT);
- EXPECT_CALL(*personal_data_, OnValidated(testing::_)).Times(0);
- personal_data_->UpdateClientValidityStates(profiles);
- EXPECT_EQ(AutofillProfile::VALID,
- profiles[1]->GetValidityState(ADDRESS_HOME_STATE,
- AutofillProfile::CLIENT));
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(true, profiles[0]->is_client_validity_states_updated());
+
+ // Update
+ profile1.SetRawInfo(EMAIL_ADDRESS, base::ASCIIToUTF16("email!"));
+ UpdateProfileOnPersonalDataManager(profile1);
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_EQ(true, profiles[0]->is_client_validity_states_updated());
+}
+
+// Verify that slow delayed validation will still work.
+TEST_F(PersonalDataManagerMockTest, UpdateClientValidityStates_Delayed) {
+ personal_data_->set_client_profile_validator_for_test(
+ TestAutofillProfileValidator::GetDelayedInstance());
+
+ AutofillProfile profile(test::GetFullProfile());
+ AddProfileToPersonalDataManager(profile);
+
+ auto profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+
+ profiles[0]->set_is_client_validity_states_updated(false);
+
+ UpdateClientValidityStatesOnPersonalDataManager(profiles);
+ profiles[0] =
+ nullptr; // make sure the async task doesn't depend on the pointer.
+
+ profiles = personal_data_->GetProfiles();
+ ASSERT_EQ(1U, profiles.size());
+ EXPECT_TRUE(profiles[0]->is_client_validity_states_updated());
}
// The validation should not happen when the feature is disabled.
@@ -7101,24 +7312,21 @@ TEST_F(PersonalDataManagerTest, UpdateClientValidityStates_Disabled) {
personal_data_->UpdateClientValidityStates(profiles);
EXPECT_FALSE(profiles[0]->is_client_validity_states_updated());
- EXPECT_EQ(AutofillProfile::UNVALIDATED,
+ EXPECT_EQ(AutofillDataModel::UNVALIDATED,
profiles[0]->GetValidityState(ADDRESS_HOME_COUNTRY,
AutofillProfile::CLIENT));
}
TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
- const std::string kIdentityManagerAccountEmail = "identity_account@email.com";
- const std::string kSyncServiceAccountEmail = "active_sync_account@email.com";
-
// Make the IdentityManager return a non-empty AccountInfo when
// GetPrimaryAccountInfo() is called.
- identity_test_env_.SetPrimaryAccount(kIdentityManagerAccountEmail);
+ identity_test_env_.SetPrimaryAccount(kPrimaryAccountEmail);
ResetPersonalDataManager(USER_MODE_NORMAL);
// Make the sync service return a non-empty AccountInfo when
// GetAuthenticatedAccountInfo() is called.
AccountInfo active_info;
- active_info.email = kSyncServiceAccountEmail;
+ active_info.email = kSyncTransportAccountEmail;
sync_service_.SetAuthenticatedAccountInfo(active_info);
// The IdentityManager's AccountInfo should be returned by default.
@@ -7129,7 +7337,7 @@ TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
/*disabled_features=*/{features::kAutofillEnableAccountWalletStorage,
features::kAutofillGetPaymentsIdentityFromSync});
- EXPECT_EQ(kIdentityManagerAccountEmail,
+ EXPECT_EQ(kPrimaryAccountEmail,
personal_data_->GetAccountInfoForPaymentsServer().email);
}
@@ -7141,7 +7349,7 @@ TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
/*enabled_features=*/{features::kAutofillEnableAccountWalletStorage},
/*disabled_features=*/{features::kAutofillGetPaymentsIdentityFromSync});
- EXPECT_EQ(kSyncServiceAccountEmail,
+ EXPECT_EQ(kSyncTransportAccountEmail,
personal_data_->GetAccountInfoForPaymentsServer().email);
}
@@ -7153,12 +7361,12 @@ TEST_F(PersonalDataManagerTest, GetAccountInfoForPaymentsServer) {
/*enabled_features=*/{features::kAutofillGetPaymentsIdentityFromSync},
/*disabled_features=*/{features::kAutofillEnableAccountWalletStorage});
- EXPECT_EQ(kSyncServiceAccountEmail,
+ EXPECT_EQ(kSyncTransportAccountEmail,
personal_data_->GetAccountInfoForPaymentsServer().email);
}
}
-TEST_F(PersonalDataManagerTest, OnGaiaCookieDeletedByUserAction) {
+TEST_F(PersonalDataManagerTest, OnAccountsCookieDeletedByUserAction) {
// Set up some sync transport opt-ins in the prefs.
::autofill::prefs::SetUserOptedInWalletSyncTransport(prefs_.get(), "account1",
true);
@@ -7166,7 +7374,7 @@ TEST_F(PersonalDataManagerTest, OnGaiaCookieDeletedByUserAction) {
prefs_->GetDictionary(prefs::kAutofillSyncTransportOptIn)->DictEmpty());
// Simulate that the cookies get cleared by the user.
- personal_data_->OnGaiaCookieDeletedByUserAction();
+ personal_data_->OnAccountsCookieDeletedByUserAction();
// Make sure the pref is now empty.
EXPECT_TRUE(
@@ -7186,7 +7394,7 @@ TEST_F(PersonalDataManagerTest, ShouldShowCardsFromAccountOption) {
// Set everything up so that the proposition should be shown.
// Set an an active secondary account.
AccountInfo active_info;
- active_info.email = "signed_in_account@email.com";
+ active_info.email = kPrimaryAccountEmail;
active_info.account_id = "account_id";
sync_service_.SetAuthenticatedAccountInfo(active_info);
sync_service_.SetIsAuthenticatedAccountPrimary(false);
@@ -7258,7 +7466,7 @@ TEST_F(PersonalDataManagerTest, ShouldShowCardsFromAccountOption) {
EXPECT_FALSE(personal_data_->ShouldShowCardsFromAccountOption());
// The metric should not be logged if the user had no server cards.
histogram_tester.ExpectTotalCount(kHistogramName, 0);
- };
+ }
// Re-set some server cards. Check that the function now returns true.
SetServerCards(server_cards);
@@ -7311,7 +7519,7 @@ TEST_F(PersonalDataManagerTest, ShouldShowCardsFromAccountOption) {
// Set everything up so that the proposition should be shown on Desktop.
// Set an an active secondary account.
AccountInfo active_info;
- active_info.email = "signed_in_account@email.com";
+ active_info.email = kPrimaryAccountEmail;
active_info.account_id = "account_id";
sync_service_.SetAuthenticatedAccountInfo(active_info);
sync_service_.SetIsAuthenticatedAccountPrimary(false);
@@ -7444,7 +7652,7 @@ TEST_F(PersonalDataManagerTest, GetSyncSigninState) {
// Simulate that the user has enabled the sync feature.
AccountInfo primary_account_info;
- primary_account_info.email = "active_sync_account@email.com";
+ primary_account_info.email = kPrimaryAccountEmail;
sync_service_.SetAuthenticatedAccountInfo(primary_account_info);
sync_service_.SetIsAuthenticatedAccountPrimary(true);
// MakePrimaryAccountAvailable is not supported on CrOS.
@@ -7477,10 +7685,9 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
///////////////////////////////////////////////////////////
// Make a non-primary account available with both a refresh token and cookie
// to be in Sync Transport for Wallet mode.
- AccountInfo active_info;
- active_info.email = "test@gmail.com";
- active_info.account_id = "account_id";
- identity_test_env_.SetPrimaryAccount(active_info.email);
+ CoreAccountInfo active_info =
+ identity_test_env_.MakeAccountAvailable(kSyncTransportAccountEmail);
+ identity_test_env_.SetCookieAccounts({{active_info.email, active_info.gaia}});
sync_service_.SetAuthenticatedAccountInfo(active_info);
sync_service_.SetIsAuthenticatedAccountPrimary(false);
sync_service_.SetActiveDataTypes(
@@ -7488,13 +7695,10 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
// Make sure there are no opt-ins recorded yet.
ASSERT_FALSE(prefs::IsUserOptedInWalletSyncTransport(prefs_.get(),
active_info.account_id));
-// The kSignedInAndWalletSyncTransportEnabled state is not available on CrOS.
-#if !defined(OS_CHROMEOS)
{
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitWithFeatures(
- /*enabled_features=*/{features::kAutofillEnableAccountWalletStorage},
- /*disabled_features=*/{});
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillEnableAccountWalletStorage);
EXPECT_EQ(AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled,
personal_data_->GetSyncSigninState());
@@ -7504,7 +7708,6 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
EXPECT_TRUE(prefs::IsUserOptedInWalletSyncTransport(
prefs_.get(), active_info.account_id));
}
-#endif // !defined(OS_CHROMEOS)
// Clear the prefs.
prefs::ClearSyncTransportOptIns(prefs_.get());
@@ -7515,10 +7718,11 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
// kSignedIn
///////////////////////////////////////////////////////////
{
+ // Without AccountWalletStorage, kSignedInAndWalletSyncTransportEnabled
+ // shouldn't be available.
base::test::ScopedFeatureList scoped_features;
- scoped_features.InitWithFeatures(
- /*enabled_features=*/{},
- /*disabled_features=*/{features::kAutofillEnableAccountWalletStorage});
+ scoped_features.InitAndDisableFeature(
+ features::kAutofillEnableAccountWalletStorage);
EXPECT_EQ(AutofillSyncSigninState::kSignedIn,
personal_data_->GetSyncSigninState());
@@ -7536,11 +7740,11 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
active_info.account_id));
///////////////////////////////////////////////////////////
- // kSignedInAndSyncFeature
+ // kSignedOut
///////////////////////////////////////////////////////////
- sync_service_.SetIsAuthenticatedAccountPrimary(true);
+ identity_test_env_.RemoveRefreshTokenForAccount(active_info.account_id);
{
- EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeature,
+ EXPECT_EQ(AutofillSyncSigninState::kSignedOut,
personal_data_->GetSyncSigninState());
// Make sure an opt-in does not get recorded even if the user accepted an
@@ -7550,19 +7754,13 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
prefs_.get(), active_info.account_id));
}
- // Clear the prefs.
- prefs::ClearSyncTransportOptIns(prefs_.get());
- ASSERT_FALSE(prefs::IsUserOptedInWalletSyncTransport(prefs_.get(),
- active_info.account_id));
-
///////////////////////////////////////////////////////////
- // kSignedOut
+ // kSignedInAndSyncFeature
///////////////////////////////////////////////////////////
-// ClearPrimaryAccount is not supported on CrOS.
-#if !defined(OS_CHROMEOS)
+ identity_test_env_.SetPrimaryAccount(active_info.email);
+ sync_service_.SetIsAuthenticatedAccountPrimary(true);
{
- identity_test_env_.ClearPrimaryAccount();
- EXPECT_EQ(AutofillSyncSigninState::kSignedOut,
+ EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeature,
personal_data_->GetSyncSigninState());
// Make sure an opt-in does not get recorded even if the user accepted an
@@ -7571,7 +7769,6 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
EXPECT_FALSE(prefs::IsUserOptedInWalletSyncTransport(
prefs_.get(), active_info.account_id));
}
-#endif // !defined(OS_CHROMEOS)
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/phone_number_i18n.cc b/chromium/components/autofill/core/browser/phone_number_i18n.cc
index f4e7e3ba8fb..956eed000e7 100644
--- a/chromium/components/autofill/core/browser/phone_number_i18n.cc
+++ b/chromium/components/autofill/core/browser/phone_number_i18n.cc
@@ -214,7 +214,7 @@ bool ParsePhoneNumber(const base::string16& value,
i18n_number->country_code_source() !=
::i18n::phonenumbers::PhoneNumber::FROM_DEFAULT_COUNTRY) {
*country_code =
- base::UTF8ToUTF16(base::IntToString(i18n_number->country_code()));
+ base::UTF8ToUTF16(base::NumberToString(i18n_number->country_code()));
}
// The region might be different from what we started with.
@@ -329,6 +329,15 @@ base::string16 GetFormattedPhoneNumberForDisplay(const AutofillProfile& profile,
return base::UTF8ToUTF16(phone);
}
+std::string FormatPhoneNationallyForDisplay(const std::string& phone_number,
+ const std::string& country_code) {
+ if (IsValidPhoneNumber(phone_number, country_code)) {
+ return FormatPhoneNumber(phone_number, country_code,
+ PhoneNumberUtil::PhoneNumberFormat::NATIONAL);
+ }
+ return phone_number;
+}
+
std::string FormatPhoneForDisplay(const std::string& phone_number,
const std::string& country_code) {
if (IsValidPhoneNumber(phone_number, country_code)) {
diff --git a/chromium/components/autofill/core/browser/phone_number_i18n.h b/chromium/components/autofill/core/browser/phone_number_i18n.h
index 5f6f7674e2d..8def9448679 100644
--- a/chromium/components/autofill/core/browser/phone_number_i18n.h
+++ b/chromium/components/autofill/core/browser/phone_number_i18n.h
@@ -90,12 +90,18 @@ bool PhoneNumbersMatch(const base::string16& number_a,
const std::string& app_locale);
// Returns the phone number from the given |profile| formatted for display.
-// If it's valid number for the country of profile, or for the |locale| given
-// as a fall back, return the number in internaional format; otherwise return
+// If it's a valid number for the profile's country or for the |locale| given
+// as a fallback, returns the number in international format; otherwise returns
// the raw number string from profile.
base::string16 GetFormattedPhoneNumberForDisplay(const AutofillProfile& profile,
const std::string& locale);
+// Returns |phone_number| in i18n::phonenumbers::PhoneNumberUtil::
+// PhoneNumberFormat::NATIONAL format if the number is valid for
+// |country_code|. Otherwise, returns the given |phone_number|.
+std::string FormatPhoneNationallyForDisplay(const std::string& phone_number,
+ const std::string& country_code);
+
// Formats the given number |phone_number| to
// i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat::INTERNATIONAL format
// by using i18n::phonenumbers::PhoneNumberUtil::Format.
diff --git a/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc b/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc
index 54103973681..a65481ec311 100644
--- a/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc
+++ b/chromium/components/autofill/core/browser/phone_number_i18n_unittest.cc
@@ -90,7 +90,7 @@ TEST_P(ParseNumberTest, ParsePhoneNumber) {
EXPECT_EQ(test_case.deduced_region, deduced_region);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
PhoneNumberI18NTest,
ParseNumberTest,
testing::Values(
@@ -272,6 +272,37 @@ TEST(PhoneNumberUtilTest, FormatPhoneForResponse) {
i18n::FormatPhoneForResponse("(1) 515-123-1234", "US"));
}
+// Tests that phone numbers are correctly formatted in a national format.
+TEST(PhoneNumberUtilTest, FormatPhoneNationallyForDisplay) {
+ // Invalid US and Brazilian numbers are not formatted.
+ EXPECT_EQ("1234567890",
+ i18n::FormatPhoneNationallyForDisplay("1234567890", "US"));
+ EXPECT_EQ("(11) 13333-4444",
+ i18n::FormatPhoneNationallyForDisplay("(11) 13333-4444", "BR"));
+ EXPECT_EQ("(11) 13333-4444",
+ i18n::FormatPhoneNationallyForDisplay("(11) 13333-4444", "IN"));
+
+ // Valid US, Canadian, UK, and Brazilian numbers are nationally formatted.
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("2024440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("+1(202)4440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("12024440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("(202)4440000", "US"));
+ EXPECT_EQ("(202) 444-0000",
+ i18n::FormatPhoneNationallyForDisplay("202-444-0000", "US"));
+ EXPECT_EQ("(819) 555-9999",
+ i18n::FormatPhoneNationallyForDisplay("+1(819)555 9999", "CA"));
+ EXPECT_EQ("(819) 555-9999",
+ i18n::FormatPhoneNationallyForDisplay("18195559999", "CA"));
+ EXPECT_EQ("020 7601 4444",
+ i18n::FormatPhoneNationallyForDisplay("+4402076014444", "UK"));
+ EXPECT_EQ("(21) 3883-5600",
+ i18n::FormatPhoneNationallyForDisplay("2138835600", "BR"));
+}
+
// Tests that the phone numbers are correctly formatted to display to the user.
TEST(PhoneNumberUtilTest, FormatPhoneForDisplay) {
// Invalid number is not formatted.
@@ -314,7 +345,7 @@ TEST_P(GetFormattedPhoneNumberForDisplayTest,
profile, GetParam().locale)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
GetFormattedPhoneNumberForDisplay,
GetFormattedPhoneNumberForDisplayTest,
testing::Values(
@@ -421,7 +452,7 @@ INSTANTIATE_TEST_CASE_P(
// This number is not a valid US number, we won't try to format.
PhoneNumberFormatCase("55 5342 8400", "US", "5553428400")));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
GetFormattedPhoneNumberForDisplay_EdgeCases,
GetFormattedPhoneNumberForDisplayTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/price_field.cc b/chromium/components/autofill/core/browser/price_field.cc
new file mode 100644
index 00000000000..59cbca3b493
--- /dev/null
+++ b/chromium/components/autofill/core/browser/price_field.cc
@@ -0,0 +1,34 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/price_field.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
+
+namespace autofill {
+
+// static
+std::unique_ptr<FormField> PriceField::Parse(AutofillScanner* scanner) {
+ AutofillField* field;
+ if (ParseFieldSpecifics(
+ scanner, base::UTF8ToUTF16(kPriceRe),
+ MATCH_DEFAULT | MATCH_NUMBER | MATCH_SELECT | MATCH_TEXT_AREA,
+ &field)) {
+ return std::make_unique<PriceField>(field);
+ }
+
+ return nullptr;
+}
+
+PriceField::PriceField(const AutofillField* field) : field_(field) {}
+
+void PriceField::AddClassifications(
+ FieldCandidatesMap* field_candidates) const {
+ AddClassification(field_, PRICE, kBasePriceParserScore, field_candidates);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/price_field.h b/chromium/components/autofill/core/browser/price_field.h
new file mode 100644
index 00000000000..65989b8ad10
--- /dev/null
+++ b/chromium/components/autofill/core/browser/price_field.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
+
+#include <memory>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "components/autofill/core/browser/form_field.h"
+
+namespace autofill {
+
+class AutofillField;
+class AutofillScanner;
+
+// Price fields are not filled by autofill, but identifying them will help to
+// reduce the number of false positives.
+class PriceField : public FormField {
+ public:
+ static std::unique_ptr<FormField> Parse(AutofillScanner* scanner);
+ PriceField(const AutofillField* field);
+
+ protected:
+ void AddClassifications(FieldCandidatesMap* field_candidates) const override;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(PriceFieldTest, ParsePrice);
+ FRIEND_TEST_ALL_PREFIXES(PriceFieldTest, ParseNonPrice);
+
+ const AutofillField* field_;
+
+ DISALLOW_COPY_AND_ASSIGN(PriceField);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PRICE_FIELD_H_
diff --git a/chromium/components/autofill/core/browser/price_field_unittest.cc b/chromium/components/autofill/core/browser/price_field_unittest.cc
new file mode 100644
index 00000000000..626cac72591
--- /dev/null
+++ b/chromium/components/autofill/core/browser/price_field_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/price_field.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/common/form_field_data.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::ASCIIToUTF16;
+
+namespace autofill {
+
+class PriceFieldTest : public testing::Test {
+ public:
+ PriceFieldTest() {}
+
+ protected:
+ std::vector<std::unique_ptr<AutofillField>> list_;
+ std::unique_ptr<PriceField> field_;
+ FieldCandidatesMap field_candidates_map_;
+
+ // Downcast for tests.
+ static std::unique_ptr<PriceField> Parse(AutofillScanner* scanner) {
+ std::unique_ptr<FormField> field = PriceField::Parse(scanner);
+ return std::unique_ptr<PriceField>(
+ static_cast<PriceField*>(field.release()));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PriceFieldTest);
+};
+
+TEST_F(PriceFieldTest, ParsePrice) {
+ FormFieldData price_field;
+ price_field.form_control_type = "text";
+
+ price_field.label = ASCIIToUTF16("name your price");
+ price_field.name = ASCIIToUTF16("userPrice");
+
+ list_.push_back(
+ std::make_unique<AutofillField>(price_field, ASCIIToUTF16("price1")));
+
+ AutofillScanner scanner(list_);
+ field_ = Parse(&scanner);
+ ASSERT_NE(nullptr, field_.get());
+ field_->AddClassifications(&field_candidates_map_);
+ ASSERT_TRUE(field_candidates_map_.find(ASCIIToUTF16("price1")) !=
+ field_candidates_map_.end());
+ EXPECT_EQ(PRICE,
+ field_candidates_map_[ASCIIToUTF16("price1")].BestHeuristicType());
+}
+
+TEST_F(PriceFieldTest, ParseNonPrice) {
+ FormFieldData address_field;
+ address_field.form_control_type = "text";
+
+ address_field.label = ASCIIToUTF16("Name");
+ address_field.name = ASCIIToUTF16("firstName");
+
+ list_.push_back(
+ std::make_unique<AutofillField>(address_field, ASCIIToUTF16("name1")));
+
+ AutofillScanner scanner(list_);
+ field_ = Parse(&scanner);
+ ASSERT_EQ(nullptr, field_.get());
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/proto/server.proto b/chromium/components/autofill/core/browser/proto/server.proto
index 079c9449ffc..86bc91e222d 100644
--- a/chromium/components/autofill/core/browser/proto/server.proto
+++ b/chromium/components/autofill/core/browser/proto/server.proto
@@ -14,7 +14,7 @@ import "password_requirements.proto";
// Request to query field suggestions for forms in a page from legacy Autofill
// API.
-// Next available id: 14
+// Next available id: 15
message AutofillQueryContents {
reserved 11; // Reserved for server use.
required string client_version = 1;
@@ -28,6 +28,7 @@ message AutofillQueryContents {
optional AutofillRandomizedFieldMetadata field_metadata = 13;
}
}
+ repeated int64 experiments = 14;
}
// Response from Autofill query on the legacy API that gives field suggestions
@@ -185,7 +186,7 @@ message AutofillRandomizedFieldMetadata {
// This message contains information about the field types in a single form.
// It is sent by the toolbar to contribute to the field type statistics.
-// Next available id: 38
+// Next available id: 39
message AutofillUploadContents {
required string client_version = 1;
required fixed64 form_signature = 2;
@@ -396,6 +397,9 @@ message AutofillUploadContents {
// Whether the fields are enclosed by a <form> tag or are unowned elements.
optional bool has_form_tag = 37;
+
+ // Captures whether or not this upload was a candidate for throttling.
+ optional bool was_throttleable = 38;
}
// This proto contains information about the validity of each field in an
diff --git a/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc b/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc
index d034c86cae0..9819106c68c 100644
--- a/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc
+++ b/chromium/components/autofill/core/browser/randomized_encoder_unittest.cc
@@ -160,9 +160,9 @@ TEST_P(RandomizedEncoderTest, EncodeLarge) {
EXPECT_EQ(expected_result, actual_result);
}
-INSTANTIATE_TEST_CASE_P(All,
- RandomizedEncoderTest,
- ::testing::ValuesIn(kEncodeParams));
+INSTANTIATE_TEST_SUITE_P(All,
+ RandomizedEncoderTest,
+ ::testing::ValuesIn(kEncodeParams));
namespace {
@@ -321,6 +321,6 @@ TEST_P(RandomizedDecoderTest, Decode) {
}
}
-INSTANTIATE_TEST_CASE_P(All,
- RandomizedDecoderTest,
- ::testing::ValuesIn(kDecodeParams));
+INSTANTIATE_TEST_SUITE_P(All,
+ RandomizedDecoderTest,
+ ::testing::ValuesIn(kDecodeParams));
diff --git a/chromium/components/autofill/core/browser/region_data_loader_impl.cc b/chromium/components/autofill/core/browser/region_data_loader_impl.cc
index 698c425dda9..c54700b584f 100644
--- a/chromium/components/autofill/core/browser/region_data_loader_impl.cc
+++ b/chromium/components/autofill/core/browser/region_data_loader_impl.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/region_data_loader_impl.h"
+#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data.h"
#include "third_party/libaddressinput/src/cpp/include/libaddressinput/region_data_builder.h"
diff --git a/chromium/components/autofill/core/browser/search_field.cc b/chromium/components/autofill/core/browser/search_field.cc
index f2b19b9461d..f684baea1f1 100644
--- a/chromium/components/autofill/core/browser/search_field.cc
+++ b/chromium/components/autofill/core/browser/search_field.cc
@@ -5,6 +5,7 @@
#include "components/autofill/core/browser/search_field.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_scanner.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
@@ -14,7 +15,8 @@ namespace autofill {
std::unique_ptr<FormField> SearchField::Parse(AutofillScanner* scanner) {
AutofillField* field;
if (ParseFieldSpecifics(scanner, base::UTF8ToUTF16(kSearchTermRe),
- MATCH_DEFAULT | MATCH_SEARCH, &field)) {
+ MATCH_DEFAULT | MATCH_SEARCH | MATCH_TEXT_AREA,
+ &field)) {
return std::make_unique<SearchField>(field);
}
diff --git a/chromium/components/autofill/core/browser/search_field.h b/chromium/components/autofill/core/browser/search_field.h
index 41d0c396d1d..bfbf77f71c3 100644
--- a/chromium/components/autofill/core/browser/search_field.h
+++ b/chromium/components/autofill/core/browser/search_field.h
@@ -13,6 +13,9 @@
namespace autofill {
+class AutofillField;
+class AutofillScanner;
+
// Search fields are not filled by autofill, but identifying them will help
// to reduce the number of false positives.
class SearchField : public FormField {
diff --git a/chromium/components/autofill/core/browser/strike_database.cc b/chromium/components/autofill/core/browser/strike_database.cc
index 0e247e7d2e3..41002501b2b 100644
--- a/chromium/components/autofill/core/browser/strike_database.cc
+++ b/chromium/components/autofill/core/browser/strike_database.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/strike_database.h"
+#include <algorithm>
#include <string>
#include <utility>
#include <vector>
@@ -39,7 +40,7 @@ StrikeDatabase::StrikeDatabase(const base::FilePath& database_dir)
StrikeDatabase::~StrikeDatabase() {}
-int StrikeDatabase::AddStrikes(int strikes_increase, const std::string key) {
+int StrikeDatabase::AddStrikes(int strikes_increase, const std::string& key) {
DCHECK(strikes_increase > 0);
int num_strikes =
strike_map_cache_.count(key) // Cache has entry for |key|.
@@ -49,29 +50,41 @@ int StrikeDatabase::AddStrikes(int strikes_increase, const std::string key) {
return num_strikes;
}
-int StrikeDatabase::RemoveStrikes(int strikes_decrease, const std::string key) {
- DCHECK(strikes_decrease > 0);
- DCHECK(strike_map_cache_.count(key));
- int num_strikes = strike_map_cache_[key].num_strikes() - strikes_decrease;
- if (num_strikes < 1) {
- ClearStrikes(key);
- return 0;
- }
+int StrikeDatabase::RemoveStrikes(int strikes_decrease,
+ const std::string& key) {
+ int num_strikes = GetStrikes(key);
+ num_strikes = std::max(0, num_strikes - strikes_decrease);
SetStrikeData(key, num_strikes);
return num_strikes;
}
-int StrikeDatabase::GetStrikes(const std::string key) {
- return strike_map_cache_.count(key) // Cache contains entry for |key|.
- ? strike_map_cache_[key].num_strikes()
- : 0;
+int StrikeDatabase::GetStrikes(const std::string& key) {
+ auto iter = strike_map_cache_.find(key);
+ return (iter != strike_map_cache_.end()) ? iter->second.num_strikes() : 0;
}
-void StrikeDatabase::ClearStrikes(const std::string key) {
+void StrikeDatabase::ClearStrikes(const std::string& key) {
strike_map_cache_.erase(key);
ClearAllProtoStrikesForKey(key, base::DoNothing());
}
+void StrikeDatabase::ClearAllStrikesForProject(
+ const std::string& project_prefix) {
+ std::vector<std::string> keys_to_delete;
+ for (std::pair<std::string, StrikeData> entry : strike_map_cache_) {
+ if (entry.first.find(project_prefix) == 0) {
+ keys_to_delete.push_back(entry.first);
+ }
+ }
+ for (std::string key : keys_to_delete)
+ ClearStrikes(key);
+}
+
+void StrikeDatabase::ClearAllStrikes() {
+ strike_map_cache_.clear();
+ ClearAllProtoStrikes(base::DoNothing());
+}
+
StrikeDatabase::StrikeDatabase()
: db_(nullptr),
database_dir_(base::FilePath(nullptr)),
@@ -106,7 +119,11 @@ void StrikeDatabase::OnDatabaseLoadKeysAndEntries(
strike_map_cache_.insert(entries->begin(), entries->end());
}
-void StrikeDatabase::SetStrikeData(const std::string key, int num_strikes) {
+void StrikeDatabase::SetStrikeData(const std::string& key, int num_strikes) {
+ if (num_strikes == 0) {
+ ClearStrikes(key);
+ return;
+ }
StrikeData data;
data.set_num_strikes(num_strikes);
data.set_last_update_timestamp(
@@ -115,7 +132,7 @@ void StrikeDatabase::SetStrikeData(const std::string key, int num_strikes) {
SetProtoStrikeData(key, data, base::DoNothing());
}
-void StrikeDatabase::GetProtoStrikes(const std::string key,
+void StrikeDatabase::GetProtoStrikes(const std::string& key,
const StrikesCallback& outer_callback) {
if (!database_initialized_) {
outer_callback.Run(false);
@@ -156,7 +173,7 @@ void StrikeDatabase::ClearAllProtoStrikesForKey(
/*keys_to_remove=*/std::move(keys_to_remove), outer_callback);
}
-void StrikeDatabase::GetProtoStrikeData(const std::string key,
+void StrikeDatabase::GetProtoStrikeData(const std::string& key,
const GetValueCallback& callback) {
if (!database_initialized_) {
callback.Run(false, nullptr);
@@ -200,4 +217,8 @@ void StrikeDatabase::UpdateCache(const std::string& key,
strike_map_cache_[key] = data;
}
+std::string StrikeDatabase::GetPrefixFromKey(const std::string& key) {
+ return key.substr(0, key.find(kKeyDeliminator));
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/strike_database.h b/chromium/components/autofill/core/browser/strike_database.h
index bea6da0aa80..8b8915df770 100644
--- a/chromium/components/autofill/core/browser/strike_database.h
+++ b/chromium/components/autofill/core/browser/strike_database.h
@@ -16,6 +16,11 @@
#include "components/leveldb_proto/public/proto_database.h"
namespace autofill {
+
+namespace {
+const char kKeyDeliminator[] = "__";
+} // namespace
+
class StrikeData;
// Manages data on whether different Autofill opportunities should be offered to
@@ -49,18 +54,26 @@ class StrikeDatabase : public KeyedService {
// Increases in-memory cache by |strikes_increase| and updates underlying
// ProtoDatabase.
- int AddStrikes(int strikes_increase, const std::string key);
+ int AddStrikes(int strikes_increase, const std::string& key);
// Removes |strikes_decrease| in-memory cache strikes, updates
// last_update_timestamp, and updates underlying ProtoDatabase.
- int RemoveStrikes(int strikes_decrease, const std::string key);
+ int RemoveStrikes(int strikes_decrease, const std::string& key);
// Returns strike count from in-memory cache.
- int GetStrikes(const std::string key);
+ int GetStrikes(const std::string& key);
+
+ // Removes database entry for |key| from in-memory cache and underlying
+ // ProtoDatabase.
+ void ClearStrikes(const std::string& key);
+
+ // Removes all database entries from in-memory cache and underlying
+ // ProtoDatabase for the whole project.
+ void ClearAllStrikesForProject(const std::string& project_prefix);
// Removes all database entries from in-memory cache and underlying
// ProtoDatabase.
- void ClearStrikes(const std::string key);
+ void ClearAllStrikes();
protected:
friend class StrikeDatabaseIntegratorBase;
@@ -92,6 +105,7 @@ class StrikeDatabase : public KeyedService {
GetIdForCreditCardSaveTest);
FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
RemoveExpiredStrikesOnLoadTest);
+ friend class SaveCardInfobarEGTestHelper;
friend class StrikeDatabaseTest;
friend class StrikeDatabaseTester;
@@ -102,13 +116,13 @@ class StrikeDatabase : public KeyedService {
std::unique_ptr<std::map<std::string, StrikeData>> entries);
// Updates the StrikeData for |key| in the cache and ProtoDatabase to have
- // |num_stikes|, and the current time as timestamp.
- void SetStrikeData(const std::string key, int num_strikes);
+ // |num_strikes|, and the current time as timestamp.
+ void SetStrikeData(const std::string& key, int num_strikes);
// Passes the number of strikes for |key| to |outer_callback|. In the case
// that the database fails to retrieve the strike update or if no entry is
// found for |key|, 0 is passed.
- virtual void GetProtoStrikes(const std::string key,
+ virtual void GetProtoStrikes(const std::string& key,
const StrikesCallback& outer_callback);
// Removes all database entries, which ensures there will be no saved strikes
@@ -123,7 +137,7 @@ class StrikeDatabase : public KeyedService {
const ClearStrikesCallback& outer_callback);
// Passes success status and StrikeData entry for |key| to |inner_callback|.
- void GetProtoStrikeData(const std::string key,
+ void GetProtoStrikeData(const std::string& key,
const GetValueCallback& inner_callback);
// Sets the entry for |key| to |strike_data|. Success status is passed to the
@@ -143,6 +157,9 @@ class StrikeDatabase : public KeyedService {
// Sets the entry for |key| in |strike_map_cache_| to |data|.
void UpdateCache(const std::string& key, const StrikeData& data);
+ // Extracts per-project prefix from |key|.
+ std::string GetPrefixFromKey(const std::string& key);
+
base::WeakPtrFactory<StrikeDatabase> weak_ptr_factory_;
};
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_base.cc b/chromium/components/autofill/core/browser/strike_database_integrator_base.cc
index f6438197ffd..5b0426188a7 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_base.cc
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_base.cc
@@ -4,6 +4,7 @@
#include "components/autofill/core/browser/strike_database_integrator_base.h"
+#include <algorithm>
#include <string>
#include <utility>
#include <vector>
@@ -19,10 +20,6 @@
namespace autofill {
-namespace {
-const char kKeyDeliminator[] = "__";
-} // namespace
-
StrikeDatabaseIntegratorBase::StrikeDatabaseIntegratorBase(
StrikeDatabase* strike_database)
: strike_database_(strike_database) {}
@@ -30,18 +27,18 @@ StrikeDatabaseIntegratorBase::StrikeDatabaseIntegratorBase(
StrikeDatabaseIntegratorBase::~StrikeDatabaseIntegratorBase() {}
bool StrikeDatabaseIntegratorBase::IsMaxStrikesLimitReached(
- const std::string id) {
+ const std::string& id) {
CheckIdUniqueness(id);
return GetStrikes(id) >= GetMaxStrikesLimit();
}
-int StrikeDatabaseIntegratorBase::AddStrike(const std::string id) {
+int StrikeDatabaseIntegratorBase::AddStrike(const std::string& id) {
CheckIdUniqueness(id);
return AddStrikes(1, id);
}
int StrikeDatabaseIntegratorBase::AddStrikes(int strikes_increase,
- const std::string id) {
+ const std::string& id) {
CheckIdUniqueness(id);
int num_strikes = strike_database_->AddStrikes(strikes_increase, GetKey(id));
base::UmaHistogramCounts1000(
@@ -50,42 +47,58 @@ int StrikeDatabaseIntegratorBase::AddStrikes(int strikes_increase,
return num_strikes;
}
-int StrikeDatabaseIntegratorBase::RemoveStrike(const std::string id) {
+int StrikeDatabaseIntegratorBase::RemoveStrike(const std::string& id) {
CheckIdUniqueness(id);
return strike_database_->RemoveStrikes(1, GetKey(id));
}
-int StrikeDatabaseIntegratorBase::RemoveStrikes(int strikes_decrease,
- const std::string id) {
+int StrikeDatabaseIntegratorBase::RemoveStrikes(int strike_decrease,
+ const std::string& id) {
CheckIdUniqueness(id);
- return strike_database_->RemoveStrikes(strikes_decrease, GetKey(id));
+ return strike_database_->RemoveStrikes(strike_decrease, GetKey(id));
}
-int StrikeDatabaseIntegratorBase::GetStrikes(const std::string id) {
+int StrikeDatabaseIntegratorBase::GetStrikes(const std::string& id) {
CheckIdUniqueness(id);
return strike_database_->GetStrikes(GetKey(id));
}
-void StrikeDatabaseIntegratorBase::ClearStrikes(const std::string id) {
+void StrikeDatabaseIntegratorBase::ClearStrikes(const std::string& id) {
CheckIdUniqueness(id);
strike_database_->ClearStrikes(GetKey(id));
}
+void StrikeDatabaseIntegratorBase::ClearAllStrikes() {
+ strike_database_->ClearAllStrikesForProject(GetProjectPrefix());
+}
+
void StrikeDatabaseIntegratorBase::RemoveExpiredStrikes() {
std::vector<std::string> expired_keys;
for (auto entry : strike_database_->strike_map_cache_) {
if (AutofillClock::Now().ToDeltaSinceWindowsEpoch().InMicroseconds() -
entry.second.last_update_timestamp() >
GetExpiryTimeMicros()) {
- if (strike_database_->GetStrikes(entry.first) > 0)
+ if (strike_database_->GetStrikes(entry.first) > 0) {
expired_keys.push_back(entry.first);
+ base::UmaHistogramCounts1000(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired." +
+ strike_database_->GetPrefixFromKey(entry.first),
+ strike_database_->GetStrikes(entry.first));
+ }
}
}
- for (std::string key : expired_keys)
- strike_database_->RemoveStrikes(1, key);
+ for (std::string key : expired_keys) {
+ int strikes_to_remove = 1;
+ // If the key is already over the limit, remove additional strikes to
+ // emulate setting it back to the limit. These are done together to avoid
+ // multiple calls to the file system ProtoDatabase.
+ strikes_to_remove +=
+ std::max(0, strike_database_->GetStrikes(key) - GetMaxStrikesLimit());
+ strike_database_->RemoveStrikes(strikes_to_remove, key);
+ }
}
-std::string StrikeDatabaseIntegratorBase::GetKey(const std::string id) {
+std::string StrikeDatabaseIntegratorBase::GetKey(const std::string& id) {
return GetProjectPrefix() + kKeyDeliminator + id;
}
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_base.h b/chromium/components/autofill/core/browser/strike_database_integrator_base.h
index 9f207da9d94..3e1bf565d8a 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_base.h
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_base.h
@@ -24,29 +24,33 @@ class StrikeDatabaseIntegratorBase {
// Returns whether or not strike count for |id| has reached the strike limit
// set by GetMaxStrikesLimit().
- bool IsMaxStrikesLimitReached(const std::string id = kSharedId);
+ bool IsMaxStrikesLimitReached(const std::string& id = kSharedId);
// Increments in-memory cache and updates underlying ProtoDatabase.
- int AddStrike(const std::string id = kSharedId);
+ int AddStrike(const std::string& id = kSharedId);
// Increases in-memory cache by |strikes_increase| and updates underlying
// ProtoDatabase.
- int AddStrikes(int strikes_increase, const std::string id = kSharedId);
+ int AddStrikes(int strikes_increase, const std::string& id = kSharedId);
// Removes an in-memory cache strike, updates last_update_timestamp, and
// updates underlying ProtoDatabase.
- int RemoveStrike(const std::string id = kSharedId);
+ int RemoveStrike(const std::string& id = kSharedId);
// Removes |strikes_decrease| in-memory cache strikes, updates
// |last_update_timestamp|, and updates underlying ProtoDatabase.
- int RemoveStrikes(int strikes_decrease, const std::string id = kSharedId);
+ int RemoveStrikes(int strikes_decrease, const std::string& id = kSharedId);
// Returns strike count from in-memory cache.
- int GetStrikes(const std::string id = kSharedId);
+ int GetStrikes(const std::string& id = kSharedId);
// Removes all database entries from in-memory cache and underlying
// ProtoDatabase.
- void ClearStrikes(const std::string id = kSharedId);
+ void ClearStrikes(const std::string& id = kSharedId);
+
+ // Removes all database entries from in-memory cache and underlying
+ // ProtoDatabase for the whole project.
+ void ClearAllStrikes();
protected:
// Removes all strikes in which it has been longer than GetExpiryTimeMicros()
@@ -56,14 +60,15 @@ class StrikeDatabaseIntegratorBase {
private:
FRIEND_TEST_ALL_PREFIXES(ChromeBrowsingDataRemoverDelegateTest,
StrikeDatabaseEmptyOnAutofillRemoveEverything);
- FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
- GetKeyForCreditCardSaveTest);
- FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
- GetIdForCreditCardSaveTest);
- FRIEND_TEST_ALL_PREFIXES(CreditCardSaveStrikeDatabaseTest,
- RemoveExpiredStrikesTest);
- FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationStrikeDatabaseTest,
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
RemoveExpiredStrikesTest);
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ GetKeyForStrikeDatabaseIntegratorUniqueIdTest);
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesUniqueIdTest);
+ FRIEND_TEST_ALL_PREFIXES(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesTestLogsUMA);
+ friend class SaveCardInfobarEGTestHelper;
friend class StrikeDatabaseTest;
friend class StrikeDatabaseTester;
@@ -79,7 +84,7 @@ class StrikeDatabaseIntegratorBase {
}
// Generates key based on project-specific string identifier.
- std::string GetKey(const std::string id);
+ std::string GetKey(const std::string& id);
// Returns a prefix unique to each project, which will be used to create
// database key.
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc
new file mode 100644
index 00000000000..c5be5139c42
--- /dev/null
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/strike_database_integrator_test_strike_database.h"
+
+#include "components/autofill/core/browser/proto/strike_data.pb.h"
+
+namespace autofill {
+
+const char kProjectPrefix[] = "StrikeDatabaseIntegratorTest";
+const int kMaxStrikesLimit = 6;
+// Expiry time is 1 year.
+const long long kExpiryTimeMicros = (long long)1000000 * 60 * 60 * 24 * 365;
+
+StrikeDatabaseIntegratorTestStrikeDatabase::
+ StrikeDatabaseIntegratorTestStrikeDatabase(StrikeDatabase* strike_database)
+ : StrikeDatabaseIntegratorBase(strike_database) {
+ RemoveExpiredStrikes();
+}
+
+StrikeDatabaseIntegratorTestStrikeDatabase::
+ ~StrikeDatabaseIntegratorTestStrikeDatabase() {}
+
+std::string StrikeDatabaseIntegratorTestStrikeDatabase::GetProjectPrefix() {
+ return kProjectPrefix;
+}
+
+int StrikeDatabaseIntegratorTestStrikeDatabase::GetMaxStrikesLimit() {
+ return kMaxStrikesLimit;
+}
+
+long long StrikeDatabaseIntegratorTestStrikeDatabase::GetExpiryTimeMicros() {
+ return kExpiryTimeMicros;
+}
+
+bool StrikeDatabaseIntegratorTestStrikeDatabase::UniqueIdsRequired() {
+ return unique_ids_required_;
+}
+
+void StrikeDatabaseIntegratorTestStrikeDatabase::SetUniqueIdsRequired(
+ bool unique_ids_required) {
+ unique_ids_required_ = unique_ids_required;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h
new file mode 100644
index 00000000000..3a50f6e75f5
--- /dev/null
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
+
+#include <string>
+
+#include "components/autofill/core/browser/strike_database.h"
+#include "components/autofill/core/browser/strike_database_integrator_base.h"
+
+namespace autofill {
+
+// Mock per-project implementation of StrikeDatabase to test the functions in
+// StrikeDatabaseIntegrator.
+class StrikeDatabaseIntegratorTestStrikeDatabase
+ : public StrikeDatabaseIntegratorBase {
+ public:
+ StrikeDatabaseIntegratorTestStrikeDatabase(StrikeDatabase* strike_database);
+ ~StrikeDatabaseIntegratorTestStrikeDatabase() override;
+
+ std::string GetProjectPrefix() override;
+ int GetMaxStrikesLimit() override;
+ long long GetExpiryTimeMicros() override;
+ bool UniqueIdsRequired() override;
+
+ void SetUniqueIdsRequired(bool unique_ids_required);
+
+ private:
+ bool unique_ids_required_ = false;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc
new file mode 100644
index 00000000000..a6e961b7fde
--- /dev/null
+++ b/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc
@@ -0,0 +1,289 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/strike_database_integrator_test_strike_database.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/files/scoped_temp_dir.h"
+#include "base/run_loop.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/autofill/core/browser/proto/strike_data.pb.h"
+#include "components/autofill/core/browser/test_autofill_clock.h"
+#include "components/autofill/core/common/autofill_clock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+class StrikeDatabaseIntegratorTestStrikeDatabaseTest : public ::testing::Test {
+ public:
+ StrikeDatabaseIntegratorTestStrikeDatabaseTest()
+ : strike_database_(new StrikeDatabase(InitFilePath())) {}
+
+ protected:
+ base::HistogramTester* GetHistogramTester() { return &histogram_tester_; }
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ StrikeDatabaseIntegratorTestStrikeDatabase strike_database_;
+
+ private:
+ static const base::FilePath InitFilePath() {
+ base::ScopedTempDir temp_dir_;
+ EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
+ const base::FilePath file_path =
+ temp_dir_.GetPath().AppendASCII("StrikeDatabaseTest");
+ return file_path;
+ }
+
+ base::HistogramTester histogram_tester_;
+};
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ MaxStrikesLimitReachedTest) {
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
+ // 3 strikes added.
+ strike_database_.AddStrikes(3);
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached());
+ // 4 strike added, total strike count is 7.
+ strike_database_.AddStrikes(4);
+ EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ StrikeDatabaseIntegratorTestNthStrikeAddedHistogram) {
+ // 2 strikes logged.
+ strike_database_.AddStrikes(2);
+ strike_database_.RemoveStrikes(2);
+ // 1 strike logged.
+ strike_database_.AddStrike();
+ // 2 strikes logged.
+ strike_database_.AddStrike();
+ std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
+ "Autofill.StrikeDatabase.NthStrikeAdded.StrikeDatabaseIntegratorTest");
+ // There should be two buckets, for strike counts of 1 and 2.
+ ASSERT_EQ(2U, buckets.size());
+ // Bucket for 1 strike should have count of 1.
+ EXPECT_EQ(1, buckets[0].count);
+ // Bucket for 2 strikes should have count of 2.
+ EXPECT_EQ(2, buckets[1].count);
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ AddStrikeForZeroAndNonZeroStrikesTest) {
+ EXPECT_EQ(0, strike_database_.GetStrikes());
+ strike_database_.AddStrike();
+ EXPECT_EQ(1, strike_database_.GetStrikes());
+ strike_database_.AddStrikes(2);
+ EXPECT_EQ(3, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForNonZeroStrikesTest) {
+ strike_database_.AddStrikes(3);
+ EXPECT_EQ(3, strike_database_.GetStrikes());
+ strike_database_.ClearStrikes();
+ EXPECT_EQ(0, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForZeroStrikesTest) {
+ strike_database_.ClearStrikes();
+ EXPECT_EQ(0, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesTest) {
+ autofill::TestAutofillClock test_clock;
+ test_clock.SetNow(AutofillClock::Now());
+ strike_database_.AddStrikes(2);
+ EXPECT_EQ(2, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // One strike should be removed.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(1, strike_database_.GetStrikes());
+
+ // Strike count is past the max limit.
+ strike_database_.AddStrikes(10);
+ EXPECT_EQ(11, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // Strike count should be one less than the max limit.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(5, strike_database_.GetStrikes());
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesTestLogsUMA) {
+ autofill::TestAutofillClock test_clock;
+ test_clock.SetNow(AutofillClock::Now());
+ strike_database_.AddStrikes(2);
+ EXPECT_EQ(2, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // One strike should be removed.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(1, strike_database_.GetStrikes());
+
+ // Strike count is past the max limit.
+ strike_database_.AddStrikes(10);
+ EXPECT_EQ(11, strike_database_.GetStrikes());
+
+ // Advance clock to past expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ // Strike count should be one less than the max limit.
+ strike_database_.RemoveExpiredStrikes();
+ EXPECT_EQ(5, strike_database_.GetStrikes());
+
+ std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired."
+ "StrikeDatabaseIntegratorTest");
+ // There should be two buckets, for strike counts of 2 and 11.
+ ASSERT_EQ(2U, buckets.size());
+ // Bucket for 2 strikes should have count of 1.
+ GetHistogramTester()->ExpectBucketCount(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired."
+ "StrikeDatabaseIntegratorTest",
+ 2, 1);
+ // Bucket for 11 strikes should have count of 1.
+ GetHistogramTester()->ExpectBucketCount(
+ "Autofill.StrikeDatabase.StrikesPresentWhenStrikeExpired."
+ "StrikeDatabaseIntegratorTest",
+ 11, 1);
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ GetKeyForStrikeDatabaseIntegratorUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ EXPECT_EQ("StrikeDatabaseIntegratorTest__1234",
+ strike_database_.GetKey(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ MaxStrikesLimitReachedUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(unique_id));
+ // 1 strike added for |unique_id|.
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(false, strike_database_.IsMaxStrikesLimitReached(unique_id));
+ // 6 strikes added for |unique_id|.
+ strike_database_.AddStrikes(6, unique_id);
+ EXPECT_EQ(true, strike_database_.IsMaxStrikesLimitReached(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ StrikeDatabaseIntegratorUniqueIdTestNthStrikeAddedHistogram) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id_1 = "1234";
+ const std::string unique_id_2 = "9876";
+ // 1st strike added for |unique_id_1|.
+ strike_database_.AddStrike(unique_id_1);
+ // 2nd strike added for |unique_id_1|.
+ strike_database_.AddStrike(unique_id_1);
+ // 1st strike added for |unique_id_2|.
+ strike_database_.AddStrike(unique_id_2);
+ std::vector<base::Bucket> buckets = GetHistogramTester()->GetAllSamples(
+ "Autofill.StrikeDatabase.NthStrikeAdded."
+ "StrikeDatabaseIntegratorTest");
+ // There should be two buckets, one for 1st strike, one for 2nd strike count.
+ ASSERT_EQ(2U, buckets.size());
+ // Both |unique_id_1| and |unique_id_2| have 1st strikes recorded.
+ EXPECT_EQ(2, buckets[0].count);
+ // Only |unique_id_1| has 2nd strike recorded.
+ EXPECT_EQ(1, buckets[1].count);
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ StrikeDatabaseIntegratorUniqueIdTestClearAllStrikes) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id_1 = "1234";
+ const std::string unique_id_2 = "9876";
+ // 1 strike added for |unique_id_1|.
+ strike_database_.AddStrike(unique_id_1);
+ // 3 strikes added for |unique_id_2|.
+ strike_database_.AddStrikes(3, unique_id_2);
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(3, strike_database_.GetStrikes(unique_id_2));
+ strike_database_.ClearAllStrikes();
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_2));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ AddStrikeForZeroAndNonZeroStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id));
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id));
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(2, strike_database_.GetStrikes(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForNonZeroStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ strike_database_.AddStrike(unique_id);
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id));
+ strike_database_.ClearStrikes(unique_id);
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ ClearStrikesForZeroStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ const std::string unique_id = "1234";
+ strike_database_.ClearStrikes(unique_id);
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id));
+}
+
+TEST_F(StrikeDatabaseIntegratorTestStrikeDatabaseTest,
+ RemoveExpiredStrikesUniqueIdTest) {
+ strike_database_.SetUniqueIdsRequired(true);
+ autofill::TestAutofillClock test_clock;
+ test_clock.SetNow(AutofillClock::Now());
+ const std::string unique_id_1 = "1234";
+ const std::string unique_id_2 = "9876";
+ strike_database_.AddStrike(unique_id_1);
+
+ // Advance clock to past the entry for |unique_id_1|'s expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ strike_database_.AddStrike(unique_id_2);
+ strike_database_.RemoveExpiredStrikes();
+
+ // |unique_id_1|'s entry should have its most recent strike expire, but
+ // |unique_id_2|'s should not.
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(1, strike_database_.GetStrikes(unique_id_2));
+
+ // Advance clock to past |unique_id_2|'s expiry time.
+ test_clock.Advance(base::TimeDelta::FromMicroseconds(
+ strike_database_.GetExpiryTimeMicros() + 1));
+
+ strike_database_.RemoveExpiredStrikes();
+
+ // |unique_id_1| and |unique_id_2| should have no more unexpired strikes.
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_1));
+ EXPECT_EQ(0, strike_database_.GetStrikes(unique_id_2));
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/strike_database_unittest.cc b/chromium/components/autofill/core/browser/strike_database_unittest.cc
index 57075bb0bac..88a5edeed45 100644
--- a/chromium/components/autofill/core/browser/strike_database_unittest.cc
+++ b/chromium/components/autofill/core/browser/strike_database_unittest.cc
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
diff --git a/chromium/components/autofill/core/browser/suggestion.cc b/chromium/components/autofill/core/browser/suggestion.cc
index c98e0cab5ec..9182bd12337 100644
--- a/chromium/components/autofill/core/browser/suggestion.cc
+++ b/chromium/components/autofill/core/browser/suggestion.cc
@@ -35,7 +35,7 @@ Suggestion::Suggestion(const std::string& v,
: frontend_id(fid),
value(base::UTF8ToUTF16(v)),
label(base::UTF8ToUTF16(l)),
- icon(base::UTF8ToUTF16(i)),
+ icon(i),
match(PREFIX_MATCH),
is_value_secondary(false) {}
diff --git a/chromium/components/autofill/core/browser/suggestion.h b/chromium/components/autofill/core/browser/suggestion.h
index bef99f87e62..0df9efe674b 100644
--- a/chromium/components/autofill/core/browser/suggestion.h
+++ b/chromium/components/autofill/core/browser/suggestion.h
@@ -53,7 +53,7 @@ struct Suggestion {
// Contains an image to display for the suggestion.
gfx::Image custom_icon;
// If |custom_icon| is empty, the name of the fallback built-in icon.
- base::string16 icon;
+ std::string icon;
MatchMode match;
bool is_value_secondary; // |value| should be displayed as secondary text.
};
diff --git a/chromium/components/autofill/core/browser/suggestion_selection.cc b/chromium/components/autofill/core/browser/suggestion_selection.cc
index 354c174d5b0..0a8d6c04a10 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection.cc
+++ b/chromium/components/autofill/core/browser/suggestion_selection.cc
@@ -69,6 +69,10 @@ std::vector<Suggestion> GetPrefixMatchedSuggestions(
matched_profiles->size() < kMaxSuggestedProfilesCount;
i++) {
AutofillProfile* profile = profiles[i];
+
+ if (profile->ShouldSkipFillingOrSuggesting(type.GetStorableType()))
+ continue;
+
base::string16 value =
GetInfoInOneLine(profile, type, comparator.app_locale());
if (value.empty())
@@ -100,7 +104,7 @@ std::vector<Suggestion> GetPrefixMatchedSuggestions(
}
std::vector<Suggestion> GetUniqueSuggestions(
- const std::vector<ServerFieldType>& other_field_types,
+ const std::vector<ServerFieldType>& field_types,
const std::string app_locale,
const std::vector<AutofillProfile*> matched_profiles,
const std::vector<Suggestion>& suggestions,
@@ -109,7 +113,7 @@ std::vector<Suggestion> GetUniqueSuggestions(
// Limit number of unique profiles as having too many makes the browser hang
// due to drawing calculations (and is also not very useful for the user).
- ServerFieldTypeSet types(other_field_types.begin(), other_field_types.end());
+ ServerFieldTypeSet types(field_types.begin(), field_types.end());
for (size_t i = 0; i < matched_profiles.size() &&
unique_suggestions.size() < kMaxUniqueSuggestionsCount;
++i) {
diff --git a/chromium/components/autofill/core/browser/suggestion_selection.h b/chromium/components/autofill/core/browser/suggestion_selection.h
index 09c64924182..0e6909e4c51 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection.h
+++ b/chromium/components/autofill/core/browser/suggestion_selection.h
@@ -34,8 +34,10 @@ std::vector<Suggestion> GetPrefixMatchedSuggestions(
// Dedupes given suggestions based on if one is a subset of the other.
// Returns unique_suggestions, and adds the corresponding profiles to
// |unique_matched_profiles|. At most |kMaxUniqueSuggestionsCount| are returned.
+// |field_types| stores all of the form's ServerFieldTypes, including that of
+// the field on which the user is currently focused.
std::vector<Suggestion> GetUniqueSuggestions(
- const std::vector<ServerFieldType>& other_field_types,
+ const std::vector<ServerFieldType>& field_types,
const std::string app_locale,
const std::vector<AutofillProfile*> matched_profiles,
const std::vector<Suggestion>& suggestions,
diff --git a/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc b/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc
index 5ee5174898e..cb36a7d90d5 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc
+++ b/chromium/components/autofill/core/browser/suggestion_selection_unittest.cc
@@ -11,10 +11,12 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_profile_comparator.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/common/autofill_clock.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,8 +31,40 @@ using testing::ResultOf;
namespace {
const std::string TEST_APP_LOCALE = "en-US";
+
+template <typename T>
+bool CompareElements(T* a, T* b) {
+ return a->Compare(*b) < 0;
+}
+
+template <typename T>
+bool ElementsEqual(T* a, T* b) {
+ return a->Compare(*b) == 0;
}
+// Verifies that two vectors have the same elements (according to T::Compare)
+// while ignoring order. This is useful because multiple profiles or credit
+// cards that are added to the SQLite DB within the same second will be returned
+// in GUID (aka random) order.
+template <typename T>
+void ExpectSameElements(const std::vector<T*>& expectations,
+ const std::vector<T*>& results) {
+ ASSERT_EQ(expectations.size(), results.size());
+
+ std::vector<T*> expectations_copy = expectations;
+ std::sort(expectations_copy.begin(), expectations_copy.end(),
+ CompareElements<T>);
+ std::vector<T*> results_copy = results;
+ std::sort(results_copy.begin(), results_copy.end(), CompareElements<T>);
+
+ EXPECT_EQ(std::mismatch(results_copy.begin(), results_copy.end(),
+ expectations_copy.begin(), ElementsEqual<T>)
+ .first,
+ results_copy.end());
+}
+
+} // anonymous namespace
+
class SuggestionSelectionTest : public testing::Test {
public:
SuggestionSelectionTest()
@@ -150,6 +184,52 @@ TEST_F(SuggestionSelectionTest, GetPrefixMatchedSuggestions_LimitProfiles) {
Not(base::ASCIIToUTF16("Marie")))));
}
+TEST_F(SuggestionSelectionTest, GetPrefixMatchedSuggestions_SkipInvalid) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillProfileServerValidation,
+ features::kAutofillProfileClientValidation},
+ /*disabled_features=*/{});
+
+ const std::unique_ptr<AutofillProfile> profile_server_invalid =
+ CreateProfileUniquePtr("Marion");
+ const std::unique_ptr<AutofillProfile> profile_client_invalid =
+ CreateProfileUniquePtr("Bob");
+ const std::unique_ptr<AutofillProfile> profile_valid =
+ CreateProfileUniquePtr("Rose");
+ const std::unique_ptr<AutofillProfile> profile_client_invalid_country_empty =
+ CreateProfileUniquePtr("Lost");
+
+ profile_server_invalid->SetValidityState(
+ ADDRESS_HOME_STATE, AutofillProfile::INVALID, AutofillProfile::SERVER);
+ profile_client_invalid->SetValidityState(
+ ADDRESS_HOME_STATE, AutofillProfile::INVALID, AutofillProfile::CLIENT);
+ profile_client_invalid_country_empty->SetValidityState(
+ ADDRESS_HOME_STATE, AutofillProfile::INVALID, AutofillProfile::CLIENT);
+ profile_client_invalid_country_empty->SetRawInfo(ADDRESS_HOME_COUNTRY,
+ base::ASCIIToUTF16(""));
+
+ const std::vector<AutofillProfile*> profiles_data = {
+ profile_server_invalid.get(), profile_client_invalid.get(),
+ profile_valid.get(), profile_client_invalid_country_empty.get()};
+
+ std::vector<AutofillProfile*> matched_profiles;
+ auto suggestions = GetPrefixMatchedSuggestions(
+ AutofillType(ADDRESS_HOME_STATE), GetCanonicalUtf16Content("C"),
+ comparator_, profiles_data, &matched_profiles);
+
+ ASSERT_EQ(2U, suggestions.size());
+ ASSERT_EQ(2U, matched_profiles.size());
+ EXPECT_THAT(suggestions,
+ ElementsAre(Field(&Suggestion::value, base::ASCIIToUTF16("CA")),
+ Field(&Suggestion::value, base::ASCIIToUTF16("CA"))));
+
+ std::vector<AutofillProfile*> expected_result;
+ expected_result.push_back(profile_valid.get());
+ expected_result.push_back(profile_client_invalid_country_empty.get());
+ ExpectSameElements(matched_profiles, expected_result);
+}
+
TEST_F(SuggestionSelectionTest, GetUniqueSuggestions_SingleDedupe) {
// Give two suggestions with the same name, and no other field to compare.
// Expect only one unique suggestion.
diff --git a/chromium/components/autofill/core/browser/suggestion_test_helpers.h b/chromium/components/autofill/core/browser/suggestion_test_helpers.h
index a5262c052fd..60084bc45a3 100644
--- a/chromium/components/autofill/core/browser/suggestion_test_helpers.h
+++ b/chromium/components/autofill/core/browser/suggestion_test_helpers.h
@@ -5,6 +5,8 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTION_TEST_HELPERS_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTION_TEST_HELPERS_H_
+#include <string>
+
#include "components/autofill/core/browser/suggestion.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -85,8 +87,8 @@ template <class EltsAreMatcher>
inline testing::Matcher<const std::vector<Suggestion>&>
SuggestionVectorIconsAre(const EltsAreMatcher& elts_are_matcher) {
return testing::MakeMatcher(
- new SuggestionVectorMembersAreMatcher<base::string16>(elts_are_matcher,
- &Suggestion::icon));
+ new SuggestionVectorMembersAreMatcher<std::string>(elts_are_matcher,
+ &Suggestion::icon));
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.cc b/chromium/components/autofill/core/browser/test_autofill_client.cc
index b26056019a3..dadbbd1dfed 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.cc
+++ b/chromium/components/autofill/core/browser/test_autofill_client.cc
@@ -6,6 +6,7 @@
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/local_card_migration_manager.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
@@ -121,10 +122,10 @@ void TestAutofillClient::ConfirmSaveAutofillProfile(
void TestAutofillClient::ConfirmSaveCreditCardLocally(
const CreditCard& card,
- bool show_prompt,
+ SaveCreditCardOptions options,
LocalSaveCardPromptCallback callback) {
confirm_save_credit_card_locally_called_ = true;
- offer_to_save_credit_card_bubble_was_shown_ = show_prompt;
+ offer_to_save_credit_card_bubble_was_shown_ = options.show_prompt;
std::move(callback).Run(AutofillClient::ACCEPTED);
}
@@ -134,16 +135,24 @@ void TestAutofillClient::ConfirmAccountNameFixFlow(
credit_card_name_fix_flow_bubble_was_shown_ = true;
std::move(callback).Run(base::string16(base::ASCIIToUTF16("Gaia Name")));
}
+
+void TestAutofillClient::ConfirmExpirationDateFixFlow(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ callback) {
+ credit_card_name_fix_flow_bubble_was_shown_ = true;
+ std::move(callback).Run(
+ base::string16(base::ASCIIToUTF16("03")),
+ base::string16(base::ASCIIToUTF16(test::NextYear().c_str())));
+}
#endif // defined(OS_ANDROID)
void TestAutofillClient::ConfirmSaveCreditCardToCloud(
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- bool should_request_name_from_user,
- bool should_request_expiration_date_from_user,
- bool show_prompt,
+ SaveCreditCardOptions options,
UploadSaveCardPromptCallback callback) {
- offer_to_save_credit_card_bubble_was_shown_ = show_prompt;
+ offer_to_save_credit_card_bubble_was_shown_ = options.show_prompt;
std::move(callback).Run(AutofillClient::ACCEPTED, {});
}
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.h b/chromium/components/autofill/core/browser/test_autofill_client.h
index c2237b15534..71baad73db0 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.h
+++ b/chromium/components/autofill/core/browser/test_autofill_client.h
@@ -69,18 +69,20 @@ class TestAutofillClient : public AutofillClient {
base::OnceClosure callback) override;
void ConfirmSaveCreditCardLocally(
const CreditCard& card,
- bool show_prompt,
+ SaveCreditCardOptions options,
LocalSaveCardPromptCallback callback) override;
#if defined(OS_ANDROID)
void ConfirmAccountNameFixFlow(
base::OnceCallback<void(const base::string16&)> callback) override;
+ void ConfirmExpirationDateFixFlow(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ callback) override;
#endif // defined(OS_ANDROID)
void ConfirmSaveCreditCardToCloud(
const CreditCard& card,
std::unique_ptr<base::DictionaryValue> legal_message,
- bool should_request_name_from_user,
- bool should_request_expiration_date_from_user,
- bool show_prompt,
+ SaveCreditCardOptions options,
UploadSaveCardPromptCallback callback) override;
void ConfirmCreditCardFillAssist(const CreditCard& card,
base::OnceClosure callback) override;
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc b/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc
index d3eba5d0ee7..8828311186a 100644
--- a/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator.cc
@@ -49,8 +49,18 @@ AutofillProfileValidator* TestAutofillProfileValidator::GetInstance() {
return &(instance.Get().autofill_profile_validator_);
}
+// static
+TestAutofillProfileValidatorDelayed*
+TestAutofillProfileValidator::GetDelayedInstance() {
+ static base::LazyInstance<TestAutofillProfileValidator>::DestructorAtExit
+ instance = LAZY_INSTANCE_INITIALIZER;
+ return &(instance.Get().autofill_profile_validator_delayed_);
+}
+
TestAutofillProfileValidator::TestAutofillProfileValidator()
- : autofill_profile_validator_(GetInputSource(), GetInputStorage()) {}
+ : autofill_profile_validator_(GetInputSource(), GetInputStorage()),
+ autofill_profile_validator_delayed_(GetInputSource(), GetInputStorage()) {
+}
TestAutofillProfileValidator::~TestAutofillProfileValidator() {}
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator.h b/chromium/components/autofill/core/browser/test_autofill_profile_validator.h
index 93b7eeee17f..6fa2fbb04a2 100644
--- a/chromium/components/autofill/core/browser/test_autofill_profile_validator.h
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator.h
@@ -8,6 +8,7 @@
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "components/autofill/core/browser/autofill_profile_validator.h"
+#include "components/autofill/core/browser/test_autofill_profile_validator_delayed.h"
namespace autofill {
@@ -15,6 +16,7 @@ namespace autofill {
class TestAutofillProfileValidator {
public:
static AutofillProfileValidator* GetInstance();
+ static TestAutofillProfileValidatorDelayed* GetDelayedInstance();
private:
friend struct base::LazyInstanceTraitsBase<TestAutofillProfileValidator>;
@@ -22,8 +24,9 @@ class TestAutofillProfileValidator {
TestAutofillProfileValidator();
~TestAutofillProfileValidator();
- // The only instance that exists.
+ // The only instance that exists of normal and delayed validators.
AutofillProfileValidator autofill_profile_validator_;
+ TestAutofillProfileValidatorDelayed autofill_profile_validator_delayed_;
DISALLOW_COPY_AND_ASSIGN(TestAutofillProfileValidator);
};
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc
new file mode 100644
index 00000000000..ed92eae2fcf
--- /dev/null
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.cc
@@ -0,0 +1,39 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/test_autofill_profile_validator_delayed.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/cancelable_callback.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+
+namespace autofill {
+namespace {
+
+const int kRulesDelayedLoadingTimeSeconds = 3;
+
+} // namespace
+
+TestAutofillProfileValidatorDelayed::TestAutofillProfileValidatorDelayed(
+ std::unique_ptr<::i18n::addressinput::Source> source,
+ std::unique_ptr<::i18n::addressinput::Storage> storage)
+ : AutofillProfileValidator(std::move(source), std::move(storage)) {}
+
+TestAutofillProfileValidatorDelayed::~TestAutofillProfileValidatorDelayed() {}
+
+void TestAutofillProfileValidatorDelayed::LoadRulesInstantly(
+ const std::string& region_code) {
+ address_validator_.LoadRules(region_code);
+}
+
+void TestAutofillProfileValidatorDelayed::LoadRulesForRegion(
+ const std::string& region_code) {
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&TestAutofillProfileValidatorDelayed::LoadRulesInstantly,
+ base::Unretained(this), region_code),
+ base::TimeDelta::FromSeconds(kRulesDelayedLoadingTimeSeconds));
+}
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h
new file mode 100644
index 00000000000..846c249ee79
--- /dev/null
+++ b/chromium/components/autofill/core/browser/test_autofill_profile_validator_delayed.h
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_PROFILE_VALIDATOR_DELAYED_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_PROFILE_VALIDATOR_DELAYED_H_
+
+#include <memory>
+#include <string>
+
+#include "components/autofill/core/browser/autofill_profile_validator.h"
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+
+namespace autofill {
+
+// Singleton that owns a single AutofillProfileValidator instance. It's a
+// delayed validator used in tests, to make sure that the system can handle
+// possible delays in the real world.
+class TestAutofillProfileValidatorDelayed : public AutofillProfileValidator {
+ public:
+ // Takes ownership of |source| and |storage|.
+ TestAutofillProfileValidatorDelayed(
+ std::unique_ptr<::i18n::addressinput::Source> source,
+ std::unique_ptr<::i18n::addressinput::Storage> storage);
+
+ ~TestAutofillProfileValidatorDelayed() override;
+
+ // Starts loading the rules for the specified |region_code|.
+ void LoadRulesForRegion(const std::string& region_code) override;
+
+ private:
+ void LoadRulesInstantly(const std::string& region_code);
+
+ DISALLOW_COPY_AND_ASSIGN(TestAutofillProfileValidatorDelayed);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_AUTOFILL_PROFILE_VALIDATOR_DELAYED_H_
diff --git a/chromium/components/autofill/core/browser/test_autofill_provider.h b/chromium/components/autofill/core/browser/test_autofill_provider.h
index 8c69b47e99e..ef533d89c24 100644
--- a/chromium/components/autofill/core/browser/test_autofill_provider.h
+++ b/chromium/components/autofill/core/browser/test_autofill_provider.h
@@ -11,7 +11,7 @@ namespace autofill {
class TestAutofillProvider : public AutofillProvider {
public:
- ~TestAutofillProvider() override{};
+ ~TestAutofillProvider() override {}
// AutofillProvider:
void OnQueryFormFieldAutofill(AutofillHandlerProxy* handler,
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc b/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc
index cc72aed5cf6..b9808476079 100644
--- a/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc
+++ b/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc
@@ -8,7 +8,6 @@
#include "components/autofill/core/browser/payments/test_payments_client.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
-#include "services/identity/public/cpp/identity_manager.h"
namespace autofill {
@@ -16,11 +15,12 @@ TestLocalCardMigrationManager::TestLocalCardMigrationManager(
AutofillDriver* driver,
AutofillClient* client,
payments::TestPaymentsClient* payments_client,
- PersonalDataManager* personal_data_manager)
+ TestPersonalDataManager* personal_data_manager)
: LocalCardMigrationManager(client,
payments_client,
"en-US",
- personal_data_manager) {}
+ personal_data_manager),
+ personal_data_manager_(personal_data_manager) {}
TestLocalCardMigrationManager::~TestLocalCardMigrationManager() {}
@@ -28,10 +28,19 @@ bool TestLocalCardMigrationManager::IsCreditCardMigrationEnabled() {
bool migration_experiment_enabled =
features::GetLocalCardMigrationExperimentalFlag() !=
features::LocalCardMigrationExperimentalFlag::kMigrationDisabled;
+
bool has_google_payments_account =
(static_cast<int64_t>(payments_client_->GetPrefService()->GetDouble(
prefs::kAutofillBillingCustomerNumber)) != 0);
- return migration_experiment_enabled && has_google_payments_account;
+
+ bool sync_feature_enabled =
+ (personal_data_manager_->GetSyncSigninState() ==
+ AutofillSyncSigninState::kSignedInAndSyncFeature);
+
+ return migration_experiment_enabled && has_google_payments_account &&
+ (sync_feature_enabled ||
+ base::FeatureList::IsEnabled(
+ features::kAutofillEnableLocalCardMigrationForNonSyncUser));
}
bool TestLocalCardMigrationManager::LocalCardMigrationWasTriggered() {
@@ -58,15 +67,22 @@ void TestLocalCardMigrationManager::OnUserAcceptedMainMigrationDialog(
LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog(selected_cards);
}
+void TestLocalCardMigrationManager::ResetSyncState(
+ AutofillSyncSigninState sync_state) {
+ personal_data_manager_->SetSyncAndSignInState(sync_state);
+}
+
void TestLocalCardMigrationManager::OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) {
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_bin_ranges) {
if (result == AutofillClient::SUCCESS) {
local_card_migration_was_triggered_ = true;
LocalCardMigrationManager::OnDidGetUploadDetails(
- is_from_settings_page, result, context_token, std::move(legal_message));
+ is_from_settings_page, result, context_token, std::move(legal_message),
+ supported_bin_ranges);
}
}
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_manager.h b/chromium/components/autofill/core/browser/test_local_card_migration_manager.h
index 97e4518eb15..722d366dd20 100644
--- a/chromium/components/autofill/core/browser/test_local_card_migration_manager.h
+++ b/chromium/components/autofill/core/browser/test_local_card_migration_manager.h
@@ -5,9 +5,14 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
+#include <memory>
#include <string>
+#include <utility>
+#include <vector>
#include "components/autofill/core/browser/local_card_migration_manager.h"
+#include "components/autofill/core/browser/sync_utils.h"
+#include "components/autofill/core/browser/test_personal_data_manager.h"
namespace autofill {
@@ -17,14 +22,13 @@ class TestPaymentsClient;
class AutofillClient;
class AutofillDriver;
-class PersonalDataManager;
class TestLocalCardMigrationManager : public LocalCardMigrationManager {
public:
TestLocalCardMigrationManager(AutofillDriver* driver,
AutofillClient* client,
payments::TestPaymentsClient* payments_client,
- PersonalDataManager* personal_data_manager);
+ TestPersonalDataManager* personal_data_manager);
~TestLocalCardMigrationManager() override;
// Override the base function. Checks the existnece of billing customer number
@@ -50,12 +54,17 @@ class TestLocalCardMigrationManager : public LocalCardMigrationManager {
void OnUserAcceptedMainMigrationDialog(
const std::vector<std::string>& selected_cards) override;
+ // Mock the Chrome Sync state in the LocalCardMigrationManager. If not set,
+ // default to AutofillSyncSigninState::kSignedInAndSyncFeature.
+ void ResetSyncState(AutofillSyncSigninState sync_state);
+
private:
void OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result,
const base::string16& context_token,
- std::unique_ptr<base::Value> legal_message) override;
+ std::unique_ptr<base::Value> legal_message,
+ std::vector<std::pair<int, int>> supported_bin_ranges) override;
bool local_card_migration_was_triggered_ = false;
@@ -63,6 +72,8 @@ class TestLocalCardMigrationManager : public LocalCardMigrationManager {
bool main_prompt_was_shown_ = false;
+ TestPersonalDataManager* personal_data_manager_;
+
DISALLOW_COPY_AND_ASSIGN(TestLocalCardMigrationManager);
};
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc b/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc
deleted file mode 100644
index cc212712538..00000000000
--- a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/autofill/core/browser/test_local_card_migration_strike_database.h"
-
-namespace autofill {
-
-TestLocalCardMigrationStrikeDatabase::TestLocalCardMigrationStrikeDatabase(
- StrikeDatabase* strike_database)
- : LocalCardMigrationStrikeDatabase(strike_database) {}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h b/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h
deleted file mode 100644
index c1cac181ceb..00000000000
--- a/chromium/components/autofill/core/browser/test_local_card_migration_strike_database.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
-
-#include "components/autofill/core/browser/local_card_migration_strike_database.h"
-
-namespace autofill {
-
-class TestLocalCardMigrationStrikeDatabase
- : public LocalCardMigrationStrikeDatabase {
- public:
- TestLocalCardMigrationStrikeDatabase(StrikeDatabase* strike_database);
-};
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/test_personal_data_manager.cc b/chromium/components/autofill/core/browser/test_personal_data_manager.cc
index 9a6e5c35765..209cf497334 100644
--- a/chromium/components/autofill/core/browser/test_personal_data_manager.cc
+++ b/chromium/components/autofill/core/browser/test_personal_data_manager.cc
@@ -19,6 +19,10 @@ void TestPersonalDataManager::OnSyncServiceInitialized(
sync_service_initialized_ = true;
}
+AutofillSyncSigninState TestPersonalDataManager::GetSyncSigninState() const {
+ return sync_and_signin_state_;
+}
+
void TestPersonalDataManager::RecordUseOf(const AutofillDataModel& data_model) {
CreditCard* credit_card = GetCreditCardWithGUID(data_model.guid().c_str());
if (credit_card)
@@ -248,7 +252,8 @@ bool TestPersonalDataManager::IsSyncFeatureEnabled() const {
return sync_feature_enabled_;
}
-AccountInfo TestPersonalDataManager::GetAccountInfoForPaymentsServer() const {
+CoreAccountInfo TestPersonalDataManager::GetAccountInfoForPaymentsServer()
+ const {
return account_info_;
}
diff --git a/chromium/components/autofill/core/browser/test_personal_data_manager.h b/chromium/components/autofill/core/browser/test_personal_data_manager.h
index ae3a7cdb449..8aedd182f36 100644
--- a/chromium/components/autofill/core/browser/test_personal_data_manager.h
+++ b/chromium/components/autofill/core/browser/test_personal_data_manager.h
@@ -28,6 +28,7 @@ class TestPersonalDataManager : public PersonalDataManager {
// for various tests, whether to skip calls to uncreated databases/services,
// or to make things easier in general to toggle.
void OnSyncServiceInitialized(syncer::SyncService* sync_service) override;
+ AutofillSyncSigninState GetSyncSigninState() const override;
void RecordUseOf(const AutofillDataModel& data_model) override;
std::string SaveImportedProfile(
const AutofillProfile& imported_profile) override;
@@ -55,7 +56,7 @@ class TestPersonalDataManager : public PersonalDataManager {
CreditCard* GetCreditCardByNumber(const std::string& number) override;
bool IsDataLoaded() const override;
bool IsSyncFeatureEnabled() const override;
- AccountInfo GetAccountInfoForPaymentsServer() const override;
+ CoreAccountInfo GetAccountInfoForPaymentsServer() const override;
// Unique to TestPersonalDataManager:
@@ -115,7 +116,11 @@ class TestPersonalDataManager : public PersonalDataManager {
void SetSyncFeatureEnabled(bool enabled) { sync_feature_enabled_ = enabled; }
- void SetAccountInfoForPayments(const AccountInfo& account_info) {
+ void SetSyncAndSignInState(AutofillSyncSigninState sync_and_signin_state) {
+ sync_and_signin_state_ = sync_and_signin_state;
+ }
+
+ void SetAccountInfoForPayments(const CoreAccountInfo& account_info) {
account_info_ = account_info;
}
@@ -129,8 +134,10 @@ class TestPersonalDataManager : public PersonalDataManager {
base::Optional<bool> autofill_credit_card_enabled_;
base::Optional<bool> autofill_wallet_import_enabled_;
bool sync_feature_enabled_ = false;
+ AutofillSyncSigninState sync_and_signin_state_ =
+ AutofillSyncSigninState::kSignedInAndSyncFeature;
bool sync_service_initialized_ = false;
- AccountInfo account_info_;
+ CoreAccountInfo account_info_;
DISALLOW_COPY_AND_ASSIGN(TestPersonalDataManager);
};
diff --git a/chromium/components/autofill/core/browser/test_strike_database.cc b/chromium/components/autofill/core/browser/test_strike_database.cc
index bb242f48306..4aee9cb4746 100644
--- a/chromium/components/autofill/core/browser/test_strike_database.cc
+++ b/chromium/components/autofill/core/browser/test_strike_database.cc
@@ -13,7 +13,7 @@ TestStrikeDatabase::TestStrikeDatabase() {}
TestStrikeDatabase::~TestStrikeDatabase() {}
void TestStrikeDatabase::GetProtoStrikes(
- const std::string key,
+ const std::string& key,
const StrikesCallback& outer_callback) {
outer_callback.Run(GetStrikesForTesting(key));
}
diff --git a/chromium/components/autofill/core/browser/test_strike_database.h b/chromium/components/autofill/core/browser/test_strike_database.h
index ebe7731cb1f..d46be27bc4b 100644
--- a/chromium/components/autofill/core/browser/test_strike_database.h
+++ b/chromium/components/autofill/core/browser/test_strike_database.h
@@ -22,7 +22,7 @@ class TestStrikeDatabase : public StrikeDatabase {
~TestStrikeDatabase() override;
// StrikeDatabase:
- void GetProtoStrikes(const std::string key,
+ void GetProtoStrikes(const std::string& key,
const StrikesCallback& outer_callback) override;
void ClearAllProtoStrikes(
const ClearStrikesCallback& outer_callback) override;
diff --git a/chromium/components/autofill/core/browser/travel_field.cc b/chromium/components/autofill/core/browser/travel_field.cc
new file mode 100644
index 00000000000..cee6b3491c7
--- /dev/null
+++ b/chromium/components/autofill/core/browser/travel_field.cc
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/travel_field.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/common/autofill_regex_constants.h"
+
+namespace autofill {
+
+TravelField::~TravelField() = default;
+
+// static
+std::unique_ptr<FormField> TravelField::Parse(AutofillScanner* scanner) {
+ if (!scanner || scanner->IsEnd()) {
+ return nullptr;
+ }
+
+ auto travel_field = std::make_unique<TravelField>();
+ if (ParseField(scanner, base::UTF8ToUTF16(kPassportRe),
+ &travel_field->passport_) ||
+ ParseField(scanner, base::UTF8ToUTF16(kTravelOriginRe),
+ &travel_field->origin_) ||
+ ParseField(scanner, base::UTF8ToUTF16(kTravelDestinationRe),
+ &travel_field->destination_) ||
+ ParseField(scanner, base::UTF8ToUTF16(kFlightRe),
+ &travel_field->flight_)) {
+ // If any regex matches, then we found a travel field.
+ return std::move(travel_field);
+ }
+
+ return nullptr;
+}
+
+void TravelField::AddClassifications(
+ FieldCandidatesMap* field_candidates) const {
+ // Simply tag all the fields as unknown types. Travel is currently used as
+ // filter.
+ AddClassification(passport_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+ AddClassification(origin_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+ AddClassification(destination_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+ AddClassification(flight_, UNKNOWN_TYPE, kBaseTravelParserScore,
+ field_candidates);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/travel_field.h b/chromium/components/autofill/core/browser/travel_field.h
new file mode 100644
index 00000000000..0608d26c450
--- /dev/null
+++ b/chromium/components/autofill/core/browser/travel_field.h
@@ -0,0 +1,33 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_TRAVEL_FIELD_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_TRAVEL_FIELD_H_
+
+#include <memory>
+
+#include "components/autofill/core/browser/autofill_scanner.h"
+#include "components/autofill/core/browser/form_field.h"
+
+namespace autofill {
+
+class TravelField : public FormField {
+ public:
+ ~TravelField() override;
+
+ static std::unique_ptr<FormField> Parse(AutofillScanner* scanner);
+
+ protected:
+ void AddClassifications(FieldCandidatesMap* field_candidates) const override;
+
+ private:
+ // All of the following fields are optional.
+ AutofillField* passport_;
+ AutofillField* origin_;
+ AutofillField* destination_;
+ AutofillField* flight_;
+};
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TRAVEL_FIELD_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc
new file mode 100644
index 00000000000..812c157cc11
--- /dev/null
+++ b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc
@@ -0,0 +1,77 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/grit/components_scaled_resources.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace autofill {
+
+CardExpirationDateFixFlowViewDelegateMobile::
+ CardExpirationDateFixFlowViewDelegateMobile(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ upload_save_card_callback)
+ : upload_save_card_callback_(std::move(upload_save_card_callback)),
+ shown_(false),
+ had_user_interaction_(false),
+ card_label_(card.NetworkAndLastFourDigits()) {
+ DCHECK(!upload_save_card_callback_.is_null());
+}
+
+CardExpirationDateFixFlowViewDelegateMobile::
+ ~CardExpirationDateFixFlowViewDelegateMobile() {
+ if (shown_ && !had_user_interaction_)
+ AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ AutofillMetrics::ExpirationDateFixFlowPromptEvent::
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_CLOSED_WITHOUT_INTERACTION);
+}
+
+int CardExpirationDateFixFlowViewDelegateMobile::GetIconId() const {
+ return IDR_AUTOFILL_GOOGLE_PAY_WITH_DIVIDER;
+}
+
+base::string16 CardExpirationDateFixFlowViewDelegateMobile::GetTitleText()
+ const {
+ return l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_SAVE_CARD_UPDATE_EXPIRATION_DATE_TITLE);
+}
+
+base::string16 CardExpirationDateFixFlowViewDelegateMobile::GetSaveButtonLabel()
+ const {
+ return l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL);
+}
+
+void CardExpirationDateFixFlowViewDelegateMobile::Accept(
+ const base::string16& month,
+ const base::string16& year) {
+ std::move(upload_save_card_callback_).Run(month, year);
+ AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ AutofillMetrics::ExpirationDateFixFlowPromptEvent::
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_ACCEPTED);
+ had_user_interaction_ = true;
+}
+
+void CardExpirationDateFixFlowViewDelegateMobile::Dismissed() {
+ AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
+ AutofillMetrics::ExpirationDateFixFlowPromptEvent::
+ EXPIRATION_DATE_FIX_FLOW_PROMPT_DISMISSED);
+ had_user_interaction_ = true;
+}
+
+void CardExpirationDateFixFlowViewDelegateMobile::Shown() {
+ AutofillMetrics::LogExpirationDateFixFlowPromptShown();
+ shown_ = true;
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h
new file mode 100644
index 00000000000..d749b79ad1f
--- /dev/null
+++ b/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h
@@ -0,0 +1,60 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/credit_card.h"
+
+namespace autofill {
+
+// Enables the user to accept or deny expiration date fix flow prompt.
+// Only used on mobile. This class is responsible for its destruction.
+// Destruction is achieved by calling delete when the prompt is
+// dismissed.
+class CardExpirationDateFixFlowViewDelegateMobile {
+ public:
+ CardExpirationDateFixFlowViewDelegateMobile(
+ const CreditCard& card,
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ upload_save_card_callback);
+
+ ~CardExpirationDateFixFlowViewDelegateMobile();
+
+ const base::string16& card_label() const { return card_label_; }
+
+ int GetIconId() const;
+ base::string16 GetTitleText() const;
+ base::string16 GetSaveButtonLabel() const;
+ void Accept(const base::string16& month, const base::string16& year);
+ void Dismissed();
+ void Shown();
+
+ private:
+ // The callback to save the credit card to Google Payments once user accepts
+ // fix flow.
+ base::OnceCallback<void(const base::string16&, const base::string16&)>
+ upload_save_card_callback_;
+
+ // Whether the prompt was shown to the user.
+ bool shown_;
+
+ // Did the user ever explicitly accept or dismiss this prompt?
+ bool had_user_interaction_;
+
+ // Label of the card describing the network and the last four digits.
+ base::string16 card_label_;
+
+ DISALLOW_COPY_AND_ASSIGN(CardExpirationDateFixFlowViewDelegateMobile);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc b/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc
index 61ef3737f53..c5d3b1f8980 100644
--- a/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc
@@ -49,7 +49,8 @@ base::string16 CardNameFixFlowViewDelegateMobile::GetInferredCardHolderName()
}
base::string16 CardNameFixFlowViewDelegateMobile::GetSaveButtonLabel() const {
- return l10n_util::GetStringUTF16(IDS_AUTOFILL_NAME_FIX_FLOW_PROMPT_SAVE_CARD);
+ return l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_FIX_FLOW_PROMPT_SAVE_CARD_LABEL);
}
void CardNameFixFlowViewDelegateMobile::Accept(const base::string16& name) {
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc b/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc
index 529554614e0..9012160a9b2 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc
+++ b/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc
@@ -500,12 +500,12 @@ TEST_P(CvcInputValidationTest, CvcInputValidation) {
delegate_->response().cvc);
}
-INSTANTIATE_TEST_CASE_P(CardUnmaskPromptControllerImplTest,
- CvcInputValidationTest,
- testing::Values(CvcCase{"123", true, "123"},
- CvcCase{"123 ", true, "123"},
- CvcCase{" 1234 ", false},
- CvcCase{"IOU", false}));
+INSTANTIATE_TEST_SUITE_P(CardUnmaskPromptControllerImplTest,
+ CvcInputValidationTest,
+ testing::Values(CvcCase{"123", true, "123"},
+ CvcCase{"123 ", true, "123"},
+ CvcCase{" 1234 ", false},
+ CvcCase{"IOU", false}));
class CvcInputAmexValidationTest
: public CardUnmaskPromptControllerImplGenericTest,
@@ -541,14 +541,14 @@ TEST_P(CvcInputAmexValidationTest, CvcInputValidation) {
delegate_->response().cvc);
}
-INSTANTIATE_TEST_CASE_P(CardUnmaskPromptControllerImplTest,
- CvcInputAmexValidationTest,
- testing::Values(CvcCase{"123", false},
- CvcCase{"123 ", false},
- CvcCase{"1234", true, "1234"},
- CvcCase{"\t1234 ", true, "1234"},
- CvcCase{" 1234", true, "1234"},
- CvcCase{"IOU$", false}));
+INSTANTIATE_TEST_SUITE_P(CardUnmaskPromptControllerImplTest,
+ CvcInputAmexValidationTest,
+ testing::Values(CvcCase{"123", false},
+ CvcCase{"123 ", false},
+ CvcCase{"1234", true, "1234"},
+ CvcCase{"\t1234 ", true, "1234"},
+ CvcCase{" 1234", true, "1234"},
+ CvcCase{"IOU$", false}));
struct ExpirationDateTestCase {
const char* input_month;
@@ -584,7 +584,7 @@ TEST_P(ExpirationDateValidationTest, ExpirationDateValidation) {
ASCIIToUTF16(exp_case.input_year)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CardUnmaskPromptControllerImplTest,
ExpirationDateValidationTest,
testing::Values(ExpirationDateTestCase{"01", "2040", true},
diff --git a/chromium/components/autofill/core/browser/validation.cc b/chromium/components/autofill/core/browser/validation.cc
index bce4371b0de..3b4bf965681 100644
--- a/chromium/components/autofill/core/browser/validation.cc
+++ b/chromium/components/autofill/core/browser/validation.cc
@@ -51,7 +51,7 @@ bool IsValidCreditCardExpirationYear(int year, const base::Time& now) {
}
bool IsValidCreditCardNumber(const base::string16& text) {
- base::string16 number = CreditCard::StripSeparators(text);
+ const base::string16 number = CreditCard::StripSeparators(text);
if (!HasCorrectLength(number))
return false;
@@ -92,12 +92,13 @@ bool HasCorrectLength(const base::string16& number) {
return true;
}
-bool PassesLuhnCheck(base::string16& number) {
+// TODO (crbug.com/927767): Add unit tests for this function.
+bool PassesLuhnCheck(const base::string16& number) {
// Use the Luhn formula [3] to validate the number.
// [3] http://en.wikipedia.org/wiki/Luhn_algorithm
int sum = 0;
bool odd = false;
- for (base::string16::reverse_iterator iter = number.rbegin();
+ for (base::string16::const_reverse_iterator iter = number.rbegin();
iter != number.rend(); ++iter) {
if (!base::IsAsciiDigit(*iter))
return false;
diff --git a/chromium/components/autofill/core/browser/validation.h b/chromium/components/autofill/core/browser/validation.h
index 5c7dccf1a65..470d07556a0 100644
--- a/chromium/components/autofill/core/browser/validation.h
+++ b/chromium/components/autofill/core/browser/validation.h
@@ -52,7 +52,7 @@ bool IsValidCreditCardNumber(const base::string16& text);
bool HasCorrectLength(const base::string16& number);
// Returns true if |number| passes the validation by Luhn formula.
-bool PassesLuhnCheck(base::string16& number);
+bool PassesLuhnCheck(const base::string16& number);
// Returns true if |code| looks like a valid credit card security code
// for the given credit card type.
diff --git a/chromium/components/autofill/core/browser/validation_unittest.cc b/chromium/components/autofill/core/browser/validation_unittest.cc
index b9a9808d306..2604226c1a6 100644
--- a/chromium/components/autofill/core/browser/validation_unittest.cc
+++ b/chromium/components/autofill/core/browser/validation_unittest.cc
@@ -188,7 +188,7 @@ TEST_P(AutofillTypeValidationTest, IsValidForType) {
}
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardExpDate,
AutofillTypeValidationTest,
testing::Values(
@@ -231,7 +231,7 @@ INSTANTIATE_TEST_CASE_P(
false,
IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED)));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardMonth,
AutofillTypeValidationTest,
testing::Values(
@@ -254,7 +254,7 @@ INSTANTIATE_TEST_CASE_P(
false,
IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRATION_MONTH)));
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardYear,
AutofillTypeValidationTest,
testing::Values(
@@ -351,7 +351,7 @@ const static std::set<std::string> kAllBasicCardNetworks{
"amex", "discover", "diners", "elo", "jcb",
"mastercard", "mir", "unionpay", "visa"};
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardNumber,
AutofillCCNumberValidationTest,
testing::Values(
@@ -433,7 +433,7 @@ TEST_P(AutofillGetCvcLengthForCardType, GetCvcLengthForCardType) {
GetCvcLengthForCardType(GetParam().card_type));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
CreditCardCvcLength,
AutofillGetCvcLengthForCardType,
testing::Values(
@@ -465,33 +465,33 @@ TEST_P(AutofillIsUPIVirtualPaymentAddress, IsUPIVirtualPaymentAddress) {
IsUPIVirtualPaymentAddress(ASCIIToUTF16("user@" + GetParam() + ".com")));
}
-INSTANTIATE_TEST_CASE_P(UPIVirtualPaymentAddress,
- AutofillIsUPIVirtualPaymentAddress,
- testing::Values("upi",
- "allbank",
- "andb",
- "axisbank",
- "barodampay",
- "mahb",
- "cnrb",
- "csbpay",
- "dcb",
- "federal",
- "hdfcbank",
- "pockets",
- "icici",
- "idfcbank",
- "indus",
- "kbl",
- "kaypay",
- "pnb",
- "sib",
- "sbi",
- "tjsb",
- "uco",
- "unionbank",
- "united",
- "vijb",
- "ybl"));
+INSTANTIATE_TEST_SUITE_P(UPIVirtualPaymentAddress,
+ AutofillIsUPIVirtualPaymentAddress,
+ testing::Values("upi",
+ "allbank",
+ "andb",
+ "axisbank",
+ "barodampay",
+ "mahb",
+ "cnrb",
+ "csbpay",
+ "dcb",
+ "federal",
+ "hdfcbank",
+ "pockets",
+ "icici",
+ "idfcbank",
+ "indus",
+ "kbl",
+ "kaypay",
+ "pnb",
+ "sib",
+ "sbi",
+ "tjsb",
+ "uco",
+ "unionbank",
+ "united",
+ "vijb",
+ "ybl"));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_change.h b/chromium/components/autofill/core/browser/webdata/autofill_change.h
index 16c6290fa60..9605de1e35b 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_change.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_change.h
@@ -97,10 +97,33 @@ class AutofillProfileDeepChange : public AutofillProfileChange {
~AutofillProfileDeepChange() override {}
- AutofillProfile profile() const { return profile_; }
+ const AutofillProfile* profile() const { return &profile_; }
+ bool is_ongoing_on_background() const { return is_ongoing_on_background_; }
+ void set_is_ongoing_on_background() const {
+ is_ongoing_on_background_ = true;
+ }
+
+ void validation_effort_made() const { validation_effort_made_ = true; }
+ bool has_validation_effort_made() const { return validation_effort_made_; }
+
+ void set_enforce_update() { enforce_update_ = true; }
+ bool enforce_update() const { return enforce_update_; }
private:
AutofillProfile profile_;
+ // Is true when the change is taking place on the database side on the
+ // background.
+ mutable bool is_ongoing_on_background_ = false;
+ // Is true when the |profile_| has gone through the validation process.
+ // Note: This could be different from the
+ // profile_.is_client_validity_states_updated. |validation_effort_made_| shows
+ // that the effort has been made, but not necessarily successful, and profile
+ // validity may or may not be updated.
+ mutable bool validation_effort_made_ = false;
+
+ // Is true when the update should happen regardless of an equal profile.
+ // (equal in the sense of AutofillProfile::EqualForUpdate)
+ mutable bool enforce_update_ = false;
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
index f05cd1227fd..bd2bff78a16 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
@@ -27,6 +27,7 @@ AutofillProfileDataTypeController::AutofillProfileDataTypeController(
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service)
: AsyncDirectoryTypeController(syncer::AUTOFILL_PROFILE,
dump_stack,
@@ -34,6 +35,7 @@ AutofillProfileDataTypeController::AutofillProfileDataTypeController(
sync_client,
syncer::GROUP_DB,
std::move(db_thread)),
+ pdm_provider_(pdm_provider),
web_data_service_(web_data_service),
callback_registered_(false),
currently_enabled_(IsEnabled()) {
@@ -53,7 +55,7 @@ void AutofillProfileDataTypeController::OnPersonalDataChanged() {
DCHECK(CalledOnValidThread());
DCHECK_EQ(state(), MODEL_STARTING);
- sync_client()->GetPersonalDataManager()->RemoveObserver(this);
+ pdm_provider_.Run()->RemoveObserver(this);
if (!web_data_service_)
return;
@@ -78,8 +80,7 @@ bool AutofillProfileDataTypeController::StartModels() {
DisableForPolicy();
return false;
}
- autofill::PersonalDataManager* personal_data =
- sync_client()->GetPersonalDataManager();
+ autofill::PersonalDataManager* personal_data = pdm_provider_.Run();
// Make sure PDM has the sync service. This is needed because in the account
// wallet data mode, PDM uses the service to determine whether to use the
@@ -118,7 +119,7 @@ bool AutofillProfileDataTypeController::StartModels() {
void AutofillProfileDataTypeController::StopModels() {
DCHECK(CalledOnValidThread());
- sync_client()->GetPersonalDataManager()->RemoveObserver(this);
+ pdm_provider_.Run()->RemoveObserver(this);
}
bool AutofillProfileDataTypeController::ReadyForStart() const {
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
index b2886eea632..4641b0d223d 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_DATA_TYPE_CONTROLLER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_DATA_TYPE_CONTROLLER_H_
+#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -16,6 +17,7 @@
namespace autofill {
class AutofillWebDataService;
+class PersonalDataManager;
} // namespace autofill
namespace syncer {
@@ -30,12 +32,16 @@ class AutofillProfileDataTypeController
: public syncer::AsyncDirectoryTypeController,
public autofill::PersonalDataManagerObserver {
public:
+ using PersonalDataManagerProvider =
+ base::RepeatingCallback<autofill::PersonalDataManager*()>;
+
// |dump_stack| is called when an unrecoverable error occurs.
AutofillProfileDataTypeController(
scoped_refptr<base::SingleThreadTaskRunner> db_thread,
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
+ const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service);
~AutofillProfileDataTypeController() override;
@@ -61,6 +67,9 @@ class AutofillProfileDataTypeController
// Report an error (which will stop the datatype asynchronously).
void DisableForPolicy();
+ // Callback that allows accessing PersonalDataManager lazily.
+ const PersonalDataManagerProvider pdm_provider_;
+
// A reference to the AutofillWebDataService for this controller.
scoped_refptr<autofill::AutofillWebDataService> web_data_service_;
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
index 4ee20ea6814..a5047b4ae5b 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -124,8 +124,9 @@ Optional<syncer::ModelError> AutofillProfileSyncBridge::MergeSyncData(
RETURN_IF_ERROR(
initial_sync_tracker.MergeSimilarEntriesForInitialSync(app_locale_));
- RETURN_IF_ERROR(
- FlushSyncTracker(std::move(metadata_change_list), &initial_sync_tracker));
+ RETURN_IF_ERROR(FlushSyncTracker(std::move(metadata_change_list),
+ &initial_sync_tracker,
+ AutofillProfileSyncChangeOrigin::kInitial));
web_data_backend_->NotifyThatSyncHasStarted(syncer::AUTOFILL_PROFILE);
return base::nullopt;
@@ -156,7 +157,8 @@ Optional<ModelError> AutofillProfileSyncBridge::ApplySyncChanges(
}
}
- return FlushSyncTracker(std::move(metadata_change_list), &tracker);
+ return FlushSyncTracker(std::move(metadata_change_list), &tracker,
+ AutofillProfileSyncChangeOrigin::kIncrementalRemote);
}
void AutofillProfileSyncBridge::GetData(StorageKeyList storage_keys,
@@ -215,6 +217,21 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
std::make_unique<syncer::SyncMetadataStoreChangeList>(
GetAutofillTable(), syncer::AUTOFILL_PROFILE);
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ bool is_converted_from_server = false;
+ if (change.type() == AutofillProfileChange::REMOVE) {
+ // The profile is not available any more so we cannot compare its value,
+ // instead we use a rougher test based on the id - whether it is a local
+ // GUID or a server id. As a result, it has a different semantics compared
+ // to AddOrUpdate.
+ is_converted_from_server = !base::IsValidGUID(change.key());
+ } else {
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+ GetAutofillTable()->GetServerProfiles(&server_profiles);
+ is_converted_from_server = IsLocalProfileEqualToServerProfile(
+ server_profiles, *change.data_model(), app_locale_);
+ }
+
switch (change.type()) {
case AutofillProfileChange::ADD:
case AutofillProfileChange::UPDATE:
@@ -222,6 +239,12 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
change.key(),
CreateEntityDataFromAutofillProfile(*change.data_model()),
metadata_change_list.get());
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
case AutofillProfileChange::REMOVE:
// Removals have no data_model() so this change can still be for a
@@ -231,6 +254,12 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
// TODO(jkrcal): implement a hash map of known storage_keys and use it
// here.
change_processor()->Delete(change.key(), metadata_change_list.get());
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileDeleteOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
case AutofillProfileChange::EXPIRE:
// EXPIRE changes are not being issued for profiles.
@@ -245,7 +274,8 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
std::unique_ptr<MetadataChangeList> metadata_change_list,
- AutofillProfileSyncDifferenceTracker* tracker) {
+ AutofillProfileSyncDifferenceTracker* tracker,
+ AutofillProfileSyncChangeOrigin origin) {
DCHECK(tracker);
RETURN_IF_ERROR(tracker->FlushToLocal(
@@ -259,6 +289,9 @@ base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
change_processor()->Put(GetStorageKeyFromAutofillProfile(*entry),
CreateEntityDataFromAutofillProfile(*entry),
metadata_change_list.get());
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(origin);
}
return static_cast<syncer::SyncMetadataStoreChangeList*>(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
index a6e50098fe8..9b449f47d66 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h
@@ -29,6 +29,7 @@ class AutofillProfileSyncDifferenceTracker;
class AutofillTable;
class AutofillWebDataBackend;
class AutofillWebDataService;
+enum class AutofillProfileSyncChangeOrigin;
// Sync bridge implementation for AUTOFILL_PROFILE model type. Takes care of
// propagating local autofill profiles to other clients as well as incorporating
@@ -90,7 +91,9 @@ class AutofillProfileSyncBridge
// Flushes changes accumulated within |tracker| both to local and to sync.
base::Optional<syncer::ModelError> FlushSyncTracker(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
- AutofillProfileSyncDifferenceTracker* tracker);
+ AutofillProfileSyncDifferenceTracker* tracker,
+ // TODO(crbug.com/904390): Remove |origin| when the investigation is over.
+ AutofillProfileSyncChangeOrigin origin);
// Synchronously load sync metadata from the autofill table and pass it to the
// processor so that it can start tracking changes.
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
index 552c2dabef6..08e50b60dfa 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
@@ -1208,7 +1208,7 @@ TEST_P(AutofillProfileSyncBridgeUpdatesUsageStatsTest, UpdatesUsageStats) {
EXPECT_THAT(GetAllLocalData(), ElementsAre(WithUsageStats(merged)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillProfileSyncBridgeTest,
AutofillProfileSyncBridgeUpdatesUsageStatsTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
index 51d3cb7ee83..8022c6abd15 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
@@ -17,6 +17,8 @@
#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_comparator.h"
+// TODO(crbug.com/904390): Remove when the investigation is over.
+#include "components/autofill/core/browser/autofill_profile_sync_util.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/form_group.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
@@ -184,6 +186,10 @@ AutofillProfileSyncableService::MergeDataAndStartSyncing(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_ADD,
CreateData(*(it.second))));
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin::kInitial);
profiles_map_[it.first] = it.second;
}
@@ -192,6 +198,10 @@ AutofillProfileSyncableService::MergeDataAndStartSyncing(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
CreateData(*(bundle.profiles_to_sync_back[i]))));
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ AutofillProfileSyncChangeOrigin::kInitial);
}
if (!new_changes.empty()) {
@@ -603,6 +613,24 @@ void AutofillProfileSyncableService::ActOnChange(
return;
}
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ bool is_converted_from_server = false;
+ if (change.type() == AutofillProfileChange::REMOVE) {
+ // The profile is not available any more so we cannot compare its value,
+ // instead we use a rougher test based on the id - whether it is a local
+ // GUID or a server id. As a result, it has a different semantics compared
+ // to AddOrUpdate.
+ is_converted_from_server = !base::IsValidGUID(change.key());
+ } else {
+ // |webdata_backend_|, used by GetAutofillTable() may be null in unit-tests.
+ if (webdata_backend_ != nullptr) {
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+ GetAutofillTable()->GetServerProfiles(&server_profiles);
+ is_converted_from_server = IsLocalProfileEqualToServerProfile(
+ server_profiles, *change.data_model(), app_locale_);
+ }
+ }
+
syncer::SyncChangeList new_changes;
DataBundle bundle;
switch (change.type()) {
@@ -616,6 +644,12 @@ void AutofillProfileSyncableService::ActOnChange(
profiles_.push_back(
std::make_unique<AutofillProfile>(*(change.data_model())));
profiles_map_[change.data_model()->guid()] = profiles_.back().get();
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
case AutofillProfileChange::UPDATE: {
auto it = profiles_map_.find(change.data_model()->guid());
@@ -625,6 +659,12 @@ void AutofillProfileSyncableService::ActOnChange(
syncer::SyncChange(FROM_HERE,
syncer::SyncChange::ACTION_UPDATE,
CreateData(*(change.data_model()))));
+
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileAddOrUpdateOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
}
case AutofillProfileChange::REMOVE: {
@@ -636,6 +676,11 @@ void AutofillProfileSyncableService::ActOnChange(
syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE,
CreateData(empty_profile)));
profiles_map_.erase(change.key());
+ // TODO(crbug.com/904390): Remove when the investigation is over.
+ ReportAutofillProfileDeleteOrigin(
+ is_converted_from_server
+ ? AutofillProfileSyncChangeOrigin::kConvertedLocal
+ : AutofillProfileSyncChangeOrigin::kTrulyLocal);
}
break;
}
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
index b4dc3f5db51..1b605e9446b 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
@@ -1557,7 +1557,7 @@ TEST_P(SyncUpdatesUsageStatsTest, SyncUpdatesUsageStats) {
autofill_syncable_service_.StopSyncing(syncer::AUTOFILL_PROFILE);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillProfileSyncableServiceTest,
SyncUpdatesUsageStatsTest,
testing::Values(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc
index 593ce4bc14c..5a9777ebc0d 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.cc
@@ -58,4 +58,4 @@ CreateAutofillWalletSpecificsForPaymentsCustomerData(
return wallet_specifics;
}
-} // namespace autofill \ No newline at end of file
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
index 14d9f4ec53d..5ca2d3bd78a 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -2797,9 +2797,8 @@ class GetFormValuesTest : public testing::TestWithParam<GetFormValuesTestCase> {
};
TEST_P(GetFormValuesTest, GetFormValuesForElementName_SubstringMatchEnabled) {
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ base::test::ScopedFeatureList features;
+ features.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
auto test_case = GetParam();
SCOPED_TRACE(testing::Message()
@@ -2831,7 +2830,7 @@ TEST_P(GetFormValuesTest, GetFormValuesForElementName_SubstringMatchEnabled) {
table_->RemoveFormElementsAddedBetween(t1, Time(), &changes);
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillTableTest,
GetFormValuesTest,
testing::Values(GetFormValuesTestCase{{"user.test", "test_user"},
@@ -2979,10 +2978,10 @@ TEST_P(AutofillTableTestPerModelType, AutofillCorruptModelTypeState) {
EXPECT_FALSE(table_->GetAllSyncMetadata(model_type, &metadata_batch));
}
-INSTANTIATE_TEST_CASE_P(AutofillTableTest,
- AutofillTableTestPerModelType,
- testing::Values(syncer::AUTOFILL,
- syncer::AUTOFILL_PROFILE));
+INSTANTIATE_TEST_SUITE_P(AutofillTableTest,
+ AutofillTableTestPerModelType,
+ testing::Values(syncer::AUTOFILL,
+ syncer::AUTOFILL_PROFILE));
TEST_F(AutofillTableTest, RemoveOrphanAutofillTableRows) {
// Populate the different tables.
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
index 98721d9d598..5f511af4a6c 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
@@ -320,7 +320,9 @@ AutofillWalletMetadataSyncBridge::AutofillWalletMetadataSyncBridge(
LoadDataCacheAndMetadata();
}
-AutofillWalletMetadataSyncBridge::~AutofillWalletMetadataSyncBridge() {}
+AutofillWalletMetadataSyncBridge::~AutofillWalletMetadataSyncBridge() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
void AutofillWalletMetadataSyncBridge::OnWalletDataTrackingStateChanged(
bool is_tracking) {
@@ -338,6 +340,7 @@ base::Optional<syncer::ModelError>
AutofillWalletMetadataSyncBridge::MergeSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// First upload local entities that are not mentioned in |entity_data|.
UploadInitialLocalData(metadata_change_list.get(), entity_data);
@@ -349,6 +352,7 @@ base::Optional<syncer::ModelError>
AutofillWalletMetadataSyncBridge::ApplySyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return MergeRemoteChanges(std::move(metadata_change_list),
std::move(entity_data));
}
@@ -369,6 +373,7 @@ void AutofillWalletMetadataSyncBridge::GetAllDataForDebugging(
std::string AutofillWalletMetadataSyncBridge::GetClientTag(
const syncer::EntityData& entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const WalletMetadataSpecifics& remote_metadata =
entity_data.specifics.wallet_metadata();
return GetClientTagForSpecificsId(remote_metadata.type(),
@@ -377,6 +382,7 @@ std::string AutofillWalletMetadataSyncBridge::GetClientTag(
std::string AutofillWalletMetadataSyncBridge::GetStorageKey(
const syncer::EntityData& entity_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return GetStorageKeyForWalletMetadataTypeAndSpecificsId(
entity_data.specifics.wallet_metadata().type(),
entity_data.specifics.wallet_metadata().id());
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
index 4306ae52280..a9322372bcb 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
@@ -81,6 +81,9 @@ const std::string kCard1StorageKey =
const char kAddr1SyncTag[] = "address-YWRkcjHvv74=";
const char kCard1SyncTag[] = "card-Y2FyZDHvv74=";
+const char kLocalAddr1ServerId[] = "e171e3ed-858a-4dd5-9bf3-8517f14ba5fc";
+const char kLocalAddr2ServerId[] = "fa232b9a-f248-4e5a-8d76-d46f821c0c5f";
+
const char kLocaleString[] = "en-US";
const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
@@ -103,17 +106,18 @@ std::string GetCardStorageKey(const std::string& specifics_id) {
WalletMetadataSpecifics::CARD, specifics_id);
}
-WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddressWithUseStats(
+WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddressWithDetails(
const std::string& specifics_id,
size_t use_count,
- int64_t use_date) {
+ int64_t use_date,
+ bool has_converted = false) {
WalletMetadataSpecifics specifics;
specifics.set_id(specifics_id);
specifics.set_type(WalletMetadataSpecifics::ADDRESS);
specifics.set_use_count(use_count);
specifics.set_use_date(use_date);
- // Set the default value according to the constructor of AutofillProfile.
- specifics.set_address_has_converted(false);
+ // False is the default value according to the constructor of AutofillProfile.
+ specifics.set_address_has_converted(has_converted);
return specifics;
}
@@ -121,22 +125,24 @@ WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddress(
const std::string& specifics_id) {
// Set default values according to the constructor of AutofillProfile (the
// clock value is overrided by TestAutofillClock in the test fixture).
- return CreateWalletMetadataSpecificsForAddressWithUseStats(
+ return CreateWalletMetadataSpecificsForAddressWithDetails(
specifics_id, /*use_count=*/1,
/*use_date=*/UseDateToProtoValue(kJune2017));
}
-WalletMetadataSpecifics CreateWalletMetadataSpecificsForCardWithUseStats(
+WalletMetadataSpecifics CreateWalletMetadataSpecificsForCardWithDetails(
const std::string& specifics_id,
size_t use_count,
- int64_t use_date) {
+ int64_t use_date,
+ const std::string& billing_address_id = "") {
WalletMetadataSpecifics specifics;
specifics.set_id(specifics_id);
specifics.set_type(WalletMetadataSpecifics::CARD);
specifics.set_use_count(use_count);
specifics.set_use_date(use_date);
- // Set the default value according to the constructor of AutofillProfile.
- specifics.set_card_billing_address_id("");
+ // "" is the default value according to the constructor of AutofillProfile;
+ // this field is Base64 encoded in the protobuf.
+ specifics.set_card_billing_address_id(GetBase64EncodedId(billing_address_id));
return specifics;
}
@@ -144,29 +150,49 @@ WalletMetadataSpecifics CreateWalletMetadataSpecificsForCard(
const std::string& specifics_id) {
// Set default values according to the constructor of AutofillProfile (the
// clock value is overrided by TestAutofillClock in the test fixture).
- return CreateWalletMetadataSpecificsForCardWithUseStats(
+ return CreateWalletMetadataSpecificsForCardWithDetails(
specifics_id, /*use_count=*/1,
/*use_date=*/UseDateToProtoValue(kJune2017));
}
-AutofillProfile CreateServerProfileWithUseStats(const std::string& server_id,
- size_t use_count,
- int64_t use_date) {
+AutofillProfile CreateServerProfileWithDetails(const std::string& server_id,
+ size_t use_count,
+ int64_t use_date,
+ bool has_converted = false) {
AutofillProfile profile = CreateServerProfile(server_id);
profile.set_use_count(use_count);
profile.set_use_date(UseDateFromProtoValue(use_date));
+ profile.set_has_converted(has_converted);
return profile;
}
-CreditCard CreateServerCreditCardWithUseStats(const std::string& server_id,
- size_t use_count,
- int64_t use_date) {
+CreditCard CreateServerCreditCardWithDetails(
+ const std::string& server_id,
+ size_t use_count,
+ int64_t use_date,
+ const std::string& billing_address_id = "") {
CreditCard card = CreateServerCreditCard(server_id);
card.set_use_count(use_count);
card.set_use_date(UseDateFromProtoValue(use_date));
+ card.set_billing_address_id(billing_address_id);
return card;
}
+AutofillProfile CreateServerProfileFromSpecifics(
+ const WalletMetadataSpecifics& specifics) {
+ return CreateServerProfileWithDetails(
+ GetBase64DecodedId(specifics.id()), specifics.use_count(),
+ specifics.use_date(), specifics.address_has_converted());
+}
+
+CreditCard CreateServerCreditCardFromSpecifics(
+ const WalletMetadataSpecifics& specifics) {
+ return CreateServerCreditCardWithDetails(
+ GetBase64DecodedId(specifics.id()), specifics.use_count(),
+ specifics.use_date(),
+ GetBase64DecodedId(specifics.card_billing_address_id()));
+}
+
void ExtractWalletMetadataSpecificsFromDataBatch(
std::unique_ptr<DataBatch> batch,
std::vector<WalletMetadataSpecifics>* output) {
@@ -182,7 +208,7 @@ std::string WalletMetadataSpecificsAsDebugString(
output << "[id: " << specifics.id()
<< ", type: " << static_cast<int>(specifics.type())
<< ", use_count: " << specifics.use_count()
- << ", use_date: " << UseDateFromProtoValue(specifics.use_date())
+ << ", use_date: " << specifics.use_date()
<< ", card_billing_address_id: "
<< (specifics.has_card_billing_address_id()
? specifics.card_billing_address_id()
@@ -256,11 +282,47 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
mock_processor_.DelegateCallsByDefaultTo(real_processor_.get());
}
- void ResetBridge() {
+ void ResetBridge(bool initial_sync_done = true) {
+ sync_pb::ModelTypeState model_type_state;
+ model_type_state.set_initial_sync_done(initial_sync_done);
+ EXPECT_TRUE(table()->UpdateModelTypeState(syncer::AUTOFILL_WALLET_METADATA,
+ model_type_state));
bridge_.reset(new AutofillWalletMetadataSyncBridge(
mock_processor_.CreateForwardingProcessor(), &backend_));
}
+ void StartSyncing(
+ const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
+ base::RunLoop loop;
+ syncer::DataTypeActivationRequest request;
+ request.error_handler = base::DoNothing();
+ real_processor_->OnSyncStarting(
+ request,
+ base::BindLambdaForTesting(
+ [&loop](std::unique_ptr<syncer::DataTypeActivationResponse>) {
+ loop.Quit();
+ }));
+ loop.Run();
+
+ ReceiveUpdates(remote_data);
+ }
+
+ void ReceiveUpdates(
+ const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
+ // Make sure each update has an updated response version so that it does not
+ // get filtered out as reflection by the processor.
+ ++response_version;
+ // After this update initial sync is for sure done.
+ sync_pb::ModelTypeState state;
+ state.set_initial_sync_done(true);
+
+ syncer::UpdateResponseDataList updates;
+ for (const WalletMetadataSpecifics& specifics : remote_data) {
+ updates.push_back(SpecificsToUpdateResponse(specifics));
+ }
+ real_processor_->OnUpdateReceived(state, updates);
+ }
+
EntityData SpecificsToEntity(const WalletMetadataSpecifics& specifics) {
EntityData data;
*data.specifics.mutable_wallet_metadata() = specifics;
@@ -269,6 +331,14 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
return data;
}
+ syncer::UpdateResponseData SpecificsToUpdateResponse(
+ const WalletMetadataSpecifics& specifics) {
+ syncer::UpdateResponseData data;
+ data.entity = SpecificsToEntity(specifics).PassToPtr();
+ data.response_version = response_version;
+ return data;
+ }
+
std::vector<WalletMetadataSpecifics> GetAllLocalData() {
std::vector<WalletMetadataSpecifics> data;
// Perform an async call synchronously for testing.
@@ -321,6 +391,7 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
MockAutofillWebDataBackend* backend() { return &backend_; }
private:
+ int response_version = 0;
autofill::TestAutofillClock test_clock_;
ScopedTempDir temp_dir_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
@@ -449,15 +520,15 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) {
// local metadata is updated.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
DontSendLowerValueToServerOnUpdate) {
- table()->SetServerProfiles({CreateServerProfileWithUseStats(
+ table()->SetServerProfiles({CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/2, /*use_date=*/5)});
- table()->SetServerCreditCards({CreateServerCreditCardWithUseStats(
+ table()->SetServerCreditCards({CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/3, /*use_date=*/6)});
ResetBridge();
- AutofillProfile updated_profile = CreateServerProfileWithUseStats(
+ AutofillProfile updated_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/1, /*use_date=*/4);
- CreditCard updated_card = CreateServerCreditCardWithUseStats(
+ CreditCard updated_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/2, /*use_date=*/5);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
@@ -472,9 +543,44 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
EXPECT_THAT(
GetAllLocalDataInclRestart(),
UnorderedElementsAre(
- EqualsSpecifics(CreateWalletMetadataSpecificsForAddressWithUseStats(
+ EqualsSpecifics(CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5)),
- EqualsSpecifics(CreateWalletMetadataSpecificsForCardWithUseStats(
+ EqualsSpecifics(CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6))));
+}
+
+// Verify that lower values of metadata are not sent to the sync server when
+// local metadata is created (tests the case when metadata with higher use
+// counts arrive before the data, the data bridge later notifies about creation
+// for data that is already there).
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ DontSendLowerValueToServerOnCreation) {
+ table()->SetServerProfiles({CreateServerProfileWithDetails(
+ kAddr1ServerId, /*use_count=*/2, /*use_date=*/5)});
+ table()->SetServerCreditCards({CreateServerCreditCardWithDetails(
+ kCard1ServerId, /*use_count=*/3, /*use_date=*/6)});
+ ResetBridge();
+
+ AutofillProfile updated_profile = CreateServerProfileWithDetails(
+ kAddr1ServerId, /*use_count=*/1, /*use_date=*/4);
+ CreditCard updated_card = CreateServerCreditCardWithDetails(
+ kCard1ServerId, /*use_count=*/2, /*use_date=*/5);
+
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ bridge()->AutofillProfileChanged(
+ AutofillProfileChange(AutofillProfileChange::ADD,
+ updated_profile.server_id(), &updated_profile));
+ bridge()->CreditCardChanged(CreditCardChange(
+ CreditCardChange::ADD, updated_card.server_id(), &updated_card));
+
+ // Check that also the local metadata did not get updated.
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(
+ EqualsSpecifics(CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5)),
+ EqualsSpecifics(CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6))));
}
@@ -482,22 +588,22 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
// metadata is updated.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
SendHigherValuesToServerOnLocalUpdate) {
- table()->SetServerProfiles({CreateServerProfileWithUseStats(
+ table()->SetServerProfiles({CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/1, /*use_date=*/2)});
- table()->SetServerCreditCards({CreateServerCreditCardWithUseStats(
+ table()->SetServerCreditCards({CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/3, /*use_date=*/4)});
ResetBridge();
- AutofillProfile updated_profile = CreateServerProfileWithUseStats(
+ AutofillProfile updated_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard updated_card = CreateServerCreditCardWithUseStats(
+ CreditCard updated_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
WalletMetadataSpecifics expected_profile_specifics =
- CreateWalletMetadataSpecificsForAddressWithUseStats(
+ CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
WalletMetadataSpecifics expected_card_specifics =
- CreateWalletMetadataSpecificsForCardWithUseStats(
+ CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(
@@ -522,16 +628,16 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
TEST_F(AutofillWalletMetadataSyncBridgeTest,
SendNewDataToServerOnLocalAddition) {
ResetBridge();
- AutofillProfile new_profile = CreateServerProfileWithUseStats(
+ AutofillProfile new_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard new_card = CreateServerCreditCardWithUseStats(
+ CreditCard new_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
WalletMetadataSpecifics expected_profile_specifics =
- CreateWalletMetadataSpecificsForAddressWithUseStats(
+ CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
WalletMetadataSpecifics expected_card_specifics =
- CreateWalletMetadataSpecificsForCardWithUseStats(
+ CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(
@@ -556,16 +662,16 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
// recreates metadata that may get deleted in the mean-time).
TEST_F(AutofillWalletMetadataSyncBridgeTest, SendNewDataToServerOnLocalUpdate) {
ResetBridge();
- AutofillProfile new_profile = CreateServerProfileWithUseStats(
+ AutofillProfile new_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard new_card = CreateServerCreditCardWithUseStats(
+ CreditCard new_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
WalletMetadataSpecifics expected_profile_specifics =
- CreateWalletMetadataSpecificsForAddressWithUseStats(
+ CreateWalletMetadataSpecificsForAddressWithDetails(
kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
WalletMetadataSpecifics expected_card_specifics =
- CreateWalletMetadataSpecificsForCardWithUseStats(
+ CreateWalletMetadataSpecificsForCardWithDetails(
kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
EXPECT_CALL(
@@ -588,9 +694,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, SendNewDataToServerOnLocalUpdate) {
// Verify that one-off deletion of existing metadata is sent to the sync server.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
DeleteExistingDataFromServerOnLocalDeletion) {
- AutofillProfile existing_profile = CreateServerProfileWithUseStats(
+ AutofillProfile existing_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard existing_card = CreateServerCreditCardWithUseStats(
+ CreditCard existing_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
table()->SetServerProfiles({existing_profile});
table()->SetServerCreditCards({existing_card});
@@ -611,9 +717,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
// Verify that deletion of non-existing metadata is not sent to the sync server.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
DoNotDeleteNonExistingDataFromServerOnLocalDeletion) {
- AutofillProfile existing_profile = CreateServerProfileWithUseStats(
+ AutofillProfile existing_profile = CreateServerProfileWithDetails(
kAddr1ServerId, /*use_count=*/10, /*use_date=*/20);
- CreditCard existing_card = CreateServerCreditCardWithUseStats(
+ CreditCard existing_card = CreateServerCreditCardWithDetails(
kCard1ServerId, /*use_count=*/30, /*use_date=*/40);
// Save only data and not metadata.
table()->SetServerAddressesData({existing_profile});
@@ -624,7 +730,6 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
ASSERT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
- EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
bridge()->AutofillProfileChanged(AutofillProfileChange(
AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr));
@@ -635,4 +740,639 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
}
+enum RemoteChangesMode {
+ INITIAL_SYNC_ADD, // Initial sync -> ADD changes.
+ LATER_SYNC_ADD, // Later sync; the client receives the data for the first
+ // time -> ADD changes.
+ LATER_SYNC_UPDATE // Later sync; the client has received the data before ->
+ // UPDATE changes.
+};
+
+// Parametrized fixture for tests that apply in the same way for all
+// RemoteChangesModes.
+class AutofillWalletMetadataSyncBridgeRemoteChangesTest
+ : public testing::WithParamInterface<RemoteChangesMode>,
+ public AutofillWalletMetadataSyncBridgeTest {
+ public:
+ AutofillWalletMetadataSyncBridgeRemoteChangesTest() {}
+ ~AutofillWalletMetadataSyncBridgeRemoteChangesTest() override {}
+
+ void ResetBridgeWithPotentialInitialSync(
+ const std::vector<WalletMetadataSpecifics>& remote_data) {
+ AutofillWalletMetadataSyncBridgeTest::ResetBridge(
+ /*initial_sync_done=*/GetParam() != INITIAL_SYNC_ADD);
+
+ if (GetParam() == LATER_SYNC_UPDATE) {
+ StartSyncing(remote_data);
+ }
+ }
+
+ void ReceivePotentiallyInitialUpdates(
+ const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
+ if (GetParam() != LATER_SYNC_UPDATE) {
+ StartSyncing(remote_data);
+ } else {
+ AutofillWalletMetadataSyncBridgeTest::ReceiveUpdates(remote_data);
+ }
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AutofillWalletMetadataSyncBridgeRemoteChangesTest);
+};
+
+// No upstream communication or local DB change happens if the server sends an
+// empty update.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest, EmptyUpdateIgnored) {
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ResetBridgeWithPotentialInitialSync({});
+ ReceivePotentiallyInitialUpdates({});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
+}
+
+// No upstream communication or local DB change happens if the server sends the
+// same data as we have locally.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest, SameDataIgnored) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({profile, card});
+
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
+// Tests that if the remote use stats are higher / newer, they should win over
+// local stats.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_RemoteWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_profile),
+ EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that if the local use stats are higher / newer, they should win over
+// remote stats.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_LocalWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/5);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(profile), _));
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
+// Tests that the conflicts are resolved component-wise (a higher use_count is
+// taken from local data, a newer use_data is taken from remote data).
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_BothWin1) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/5);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/50);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile),
+ EqualsSpecifics(merged_card)));
+}
+
+// Tests that the conflicts are resolved component-wise, like the previous test,
+// only the other way around (a higher use_count is taken from remote data, a
+// newer use_data is taken from local data).
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferHigherValues_BothWin2) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/2, /*use_date=*/50);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/5);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/50);
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile),
+ EqualsSpecifics(merged_card)));
+}
+
+// No merge logic is applied if local data has initial use_count (=1). In this
+// situation, we just take over the remote entity completely.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_PreferRemoteIfLocalHasInitialUseCount) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/1, /*use_date=*/60);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({profile, card});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/20, /*use_date=*/5);
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates(
+ {updated_remote_profile, updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_profile),
+ EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that with a conflict in billing_address_id, we prefer an ID of a local
+// profile over an ID of a server profile. In this test, the preferred ID is in
+// the remote update that we need to store locally.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferLocalBillingAddressId_RemoteWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that with a conflict in billing_address_id, we prefer an ID of a local
+// profile over an ID of a server profile. In this test, the preferred ID is in
+// the local data that we need to upstream.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferLocalBillingAddressId_LocalWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(card)));
+}
+
+// Tests that if both addresses have billing address ids of local profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// remote entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfLocalIds_RemoteWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kLocalAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that if both addresses have billing address ids of local profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// local entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfLocalIds_LocalWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kLocalAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kLocalAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(card)));
+}
+
+// Tests that if both addresses have billing address ids of server profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// remote entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_RemoteWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_card)));
+}
+
+// Tests that if both addresses have billing address ids of server profiles, we
+// prefer the one from the most recently used entity. In this test, it is the
+// local entity.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_LocalWins) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/6,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(card)));
+}
+
+// Tests that the conflict resolution happens component-wise. To avoid
+// combinatorial explosion, this only tests when both have billing address ids
+// of server profiles, one entity is more recently used but the other entity has
+// a higher use_count. We should pick the billing_address_id of the newer one
+// but have the use_count updated to the maximum as well. In this test, the
+// remote entity is the more recently used.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_BothWin1) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_card)));
+}
+
+// Tests that the conflict resolution happens component-wise. To avoid
+// combinatorial explosion, this only tests when both have billing address ids
+// of server profiles, one entity is more recently used but the other entity has
+// a higher use_count. We should pick the billing_address_id of the newer one
+// but have the use_count updated to the maximum as well. In this test, the
+// local entity is the more recently used.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Card_PreferNewerBillingAddressOutOfServerIds_BothWin2) {
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/3, /*use_date=*/60,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+ ResetBridgeWithPotentialInitialSync({card});
+
+ WalletMetadataSpecifics updated_remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/6,
+ /*billing_address_id=*/kAddr2ServerId);
+
+ WalletMetadataSpecifics merged_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/60,
+ /*billing_address_id=*/kAddr1ServerId);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_card)));
+}
+
+// Tests that if the has_converted bit differs, we always end up with the true
+// value. This test has the remote entity converted which should get updated in
+// the local DB.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_RemoteWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(updated_remote_profile)));
+}
+
+// Tests that if the has_converted bit differs, we always end up with the true
+// value. This test has the local entity converted which should get upstreamed.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_LocalWins) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(profile), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile)));
+}
+
+// Tests that the conflict resolution happens component-wise. If one entity
+// has_converted but the other entity has higher use_count, we should end up
+// with an entity that has_converted and has the higher use_count. This test has
+// the remote entity converted.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_BothWin1) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile)));
+}
+
+// Tests that the conflict resolution happens component-wise. If one entity
+// has_converted but the other entity has higher use_count, we should end up
+// with an entity that has_converted and has the higher use_count. This test has
+// the local entity converted.
+TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ Conflict_Address_HasConverted_BothWin2) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/1, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ ResetBridgeWithPotentialInitialSync({profile});
+
+ WalletMetadataSpecifics updated_remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/false);
+
+ WalletMetadataSpecifics merged_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/50,
+ /*has_converted=*/true);
+
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+
+ ReceivePotentiallyInitialUpdates({updated_remote_profile});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(merged_profile)));
+}
+
+INSTANTIATE_TEST_SUITE_P(,
+ AutofillWalletMetadataSyncBridgeRemoteChangesTest,
+ ::testing::Values(INITIAL_SYNC_ADD,
+ LATER_SYNC_ADD,
+ LATER_SYNC_UPDATE));
+
} // namespace autofill
+
+namespace sync_pb {
+
+// Makes the GMock matchers print out a readable version of the protobuf.
+void PrintTo(const WalletMetadataSpecifics& specifics, std::ostream* os) {
+ *os << autofill::WalletMetadataSpecificsAsDebugString(specifics);
+}
+
+} // namespace sync_pb
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
index 86fd8a07dff..7b88c1b8b36 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
@@ -511,8 +511,6 @@ syncer::SyncError AutofillWalletMetadataSyncableService::ProcessSyncChanges(
// get rid of this hack.
DCHECK(!ignore_multiple_changed_notification_);
ignore_multiple_changed_notification_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " ProcessSyncChanges notify the PDM";
web_data_backend_->NotifyOfMultipleAutofillChanges();
ignore_multiple_changed_notification_ = false;
}
@@ -541,13 +539,9 @@ void AutofillWalletMetadataSyncableService::AutofillProfileChanged(
it->GetSpecifics().wallet_metadata();
const AutofillProfile& local = *change.data_model();
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " AutofillProfileChanged " << local;
if (!AreLocalUseStatsUpdated(remote, local) &&
!IsLocalHasConvertedStatusUpdated(remote, local)) {
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " Nothing has changed, not syncing up.";
return;
}
@@ -573,8 +567,11 @@ void AutofillWalletMetadataSyncableService::CreditCardChanged(
server_id, sync_pb::WalletMetadataSpecifics::CARD, &cache_);
if (it == cache_.end())
return;
- // Implicitly, we filter out ADD (not in cache) and REMOVE (!data_model()).
- DCHECK(change.type() == AutofillProfileChange::UPDATE);
+ // Deletions and creations are treated by Wallet data sync (and propagated
+ // here by AutofillMultipleChanged()). We only treat updates here.
+ if (change.type() != AutofillProfileChange::UPDATE) {
+ return;
+ }
const sync_pb::WalletMetadataSpecifics& remote =
it->GetSpecifics().wallet_metadata();
@@ -662,8 +659,6 @@ bool AutofillWalletMetadataSyncableService::GetLocalData(
bool AutofillWalletMetadataSyncableService::UpdateAddressStats(
const AutofillProfile& profile) {
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " Applying change from sync " << profile;
return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase())
->UpdateServerAddressMetadata(profile);
}
@@ -763,8 +758,6 @@ syncer::SyncMergeResult AutofillWalletMetadataSyncableService::MergeData(
// get rid of this hack.
DCHECK(!ignore_multiple_changed_notification_);
ignore_multiple_changed_notification_ = true;
- // TODO(crbug.com/915229): Remove once the investigation is over.
- DLOG(WARNING) << this << " MergeData notify the PDM";
web_data_backend_->NotifyOfMultipleAutofillChanges();
ignore_multiple_changed_notification_ = false;
}
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
index 8631ea78944..a3a4494ddb1 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -21,6 +21,7 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_util.h"
+#include "components/sync/base/data_type_histogram.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/model/entity_data.h"
#include "components/sync/model/mutable_data_batch.h"
@@ -253,8 +254,7 @@ bool AutofillWalletSyncBridge::SupportsIncrementalUpdates() const {
return false;
}
-AutofillWalletSyncBridge::StopSyncResponse
-AutofillWalletSyncBridge::ApplyStopSyncChanges(
+void AutofillWalletSyncBridge::ApplyStopSyncChanges(
std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list) {
// If a metadata change list gets passed in, that means sync is actually
// disabled, so we want to delete the payments data.
@@ -262,11 +262,25 @@ AutofillWalletSyncBridge::ApplyStopSyncChanges(
if (initial_sync_done_) {
active_callback_.Run(false);
}
+
+ // Report count of entities to delete. This use case should be pretty rare
+ // so it is okay to read it from DB again.
+ // TODO(crbug.com/853688): Remove when wallet data is launched on USS, incl.
+ // the helper function SyncWalletDataRecordClearedEntitiesCount().
+ std::vector<std::unique_ptr<AutofillProfile>> profiles;
+ std::vector<std::unique_ptr<CreditCard>> cards;
+ std::unique_ptr<PaymentsCustomerData> customer_data;
+ if (GetAutofillTable()->GetServerProfiles(&profiles) &&
+ GetAutofillTable()->GetServerCreditCards(&cards) &&
+ GetAutofillTable()->GetPaymentsCustomerData(&customer_data)) {
+ int count = profiles.size() + cards.size() + (customer_data ? 1 : 0);
+ SyncWalletDataRecordClearedEntitiesCount(count);
+ }
+
SetSyncData(syncer::EntityChangeList());
initial_sync_done_ = false;
}
- return StopSyncResponse::kModelStillReadyToSync;
}
void AutofillWalletSyncBridge::GetAllDataForTesting(DataCallback callback) {
@@ -327,6 +341,13 @@ void AutofillWalletSyncBridge::SetSyncData(
wallet_data_changed |=
SetWalletAddresses(std::move(wallet_addresses), should_log_diff);
+ // Commit the transaction to make sure the data and the metadata with the
+ // new progress marker is written down (especially on Android where we
+ // cannot rely on commiting transactions on shutdown). We need to commit
+ // even if the wallet data has not changed because the model type state incl.
+ // the progress marker always changes.
+ web_data_backend_->CommitChanges();
+
if (web_data_backend_ && wallet_data_changed)
web_data_backend_->NotifyOfMultipleAutofillChanges();
}
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
index 17ea21c91bb..3f91a3c6276 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h
@@ -66,9 +66,8 @@ class AutofillWalletSyncBridge : public base::SupportsUserData::Data,
std::string GetClientTag(const syncer::EntityData& entity_data) override;
std::string GetStorageKey(const syncer::EntityData& entity_data) override;
bool SupportsIncrementalUpdates() const override;
- StopSyncResponse ApplyStopSyncChanges(
- std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list)
- override;
+ void ApplyStopSyncChanges(std::unique_ptr<syncer::MetadataChangeList>
+ delete_metadata_change_list) override;
// Sends all Wallet Data to the |callback| and keeps all the strings in their
// original format (whereas GetAllDataForDebugging() has to make them UTF-8).
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
index 97c9520760b..9549f984cc4 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
@@ -369,7 +369,7 @@ class AutofillWalletSyncBridgeTest : public UssSwitchToggler,
base::MockCallback<base::RepeatingCallback<void(bool)>>* active_callback() {
return &active_callback_;
- };
+ }
private:
autofill::TestAutofillClock test_clock_;
@@ -487,6 +487,7 @@ TEST_P(AutofillWalletSyncBridgeTest, MergeSyncData_NewWalletAddressAndCard) {
&customer_data_specifics);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
AddChange(address2.server_id(), address2)));
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
@@ -533,6 +534,7 @@ TEST_P(AutofillWalletSyncBridgeTest,
&customer_data_specifics);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({profile_specifics, card_specifics, customer_data_specifics});
if (IsWalletMetadataOnUSS()) {
@@ -573,6 +575,7 @@ TEST_P(AutofillWalletSyncBridgeTest, MergeSyncData_NewPaymentsCustomerData) {
&customer_data_specifics2);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0);
EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0);
StartSyncing({profile_specifics, card_specifics, customer_data_specifics2});
@@ -596,6 +599,7 @@ TEST_P(AutofillWalletSyncBridgeTest, MergeSyncData_NoWalletAddressOrCard) {
table()->SetServerCreditCards({local_card});
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
RemoveChange(local_profile.server_id())));
EXPECT_CALL(*backend(),
@@ -636,6 +640,8 @@ TEST_P(AutofillWalletSyncBridgeTest,
&customer_data_specifics);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker on the client.
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0);
EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0);
StartSyncing({profile_specifics, card_specifics, customer_data_specifics});
@@ -672,6 +678,7 @@ TEST_P(AutofillWalletSyncBridgeTest,
SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data,
&customer_data_specifics);
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
RemoveChange(profile2.server_id())));
@@ -817,6 +824,7 @@ TEST_P(AutofillWalletSyncBridgeTest, ApplyStopSyncChanges_ClearAllData) {
CreditCard local_card = test::GetMaskedServerCard();
table()->SetServerCreditCards({local_card});
+ EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
RemoveChange(local_profile.server_id())));
@@ -846,6 +854,8 @@ TEST_P(AutofillWalletSyncBridgeTest, ApplyStopSyncChanges_KeepData) {
CreditCard local_card = test::GetMaskedServerCard();
table()->SetServerCreditCards({local_card});
+ // We do not write to DB at all, so we should not commit any changes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0);
EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0);
@@ -884,8 +894,8 @@ TEST_P(AutofillWalletSyncBridgeTest, NotifiesWhenActivelySyncing) {
bridge()->ApplyStopSyncChanges(/*delete_metadata_change_list=*/nullptr);
}
-INSTANTIATE_TEST_CASE_P(USS,
- AutofillWalletSyncBridgeTest,
- ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(USS,
+ AutofillWalletSyncBridgeTest,
+ ::testing::Values(false, true));
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
index 43ff06e9619..aa37b89bc4d 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
@@ -34,6 +34,12 @@ class AutofillWebDataBackend {
// Remove expired elements from the database and commit if needed.
virtual void RemoveExpiredFormElements() = 0;
+ // Commits the currently open transaction in the database. Should be only used
+ // by parties that talk directly to the database and not through the
+ // WebDatabase backend (notably Sync reacting to remote changes coming from
+ // the server).
+ virtual void CommitChanges() = 0;
+
// Notifies listeners on the DB sequence that an AutofillProfile has been
// added/removed/updated in the WebDatabase.
// NOTE: This method is intended to be called from the DB sequence. The UI
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
index e69f6834bc4..d7cb6af4768 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -25,6 +25,12 @@ using base::Time;
namespace autofill {
+namespace {
+WebDatabase::State DoNothingAndCommit(WebDatabase* db) {
+ return WebDatabase::COMMIT_NEEDED;
+}
+} // namespace
+
AutofillWebDataBackendImpl::AutofillWebDataBackendImpl(
scoped_refptr<WebDatabaseBackend> web_database_backend,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
@@ -64,6 +70,10 @@ WebDatabase* AutofillWebDataBackendImpl::GetDatabase() {
return web_database_backend_->database();
}
+void AutofillWebDataBackendImpl::CommitChanges() {
+ web_database_backend_->ExecuteWriteTask(Bind(&DoNothingAndCommit));
+}
+
void AutofillWebDataBackendImpl::RemoveExpiredFormElements() {
web_database_backend_->ExecuteWriteTask(
Bind(&AutofillWebDataBackendImpl::RemoveExpiredFormElementsImpl, this));
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
index 9b4a5a2abb6..b508bda93b1 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h
@@ -70,6 +70,7 @@ class AutofillWebDataBackendImpl
void NotifyOfCreditCardChanged(const CreditCardChange& change) override;
void NotifyOfMultipleAutofillChanges() override;
void NotifyThatSyncHasStarted(syncer::ModelType model_type) override;
+ void CommitChanges() override;
// TODO(crbug.com/920214): Deprecated, will be removed when
// autocomplete retention policy shipped. Replaced by
diff --git a/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h b/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h
index 7b747246664..3368878abf0 100644
--- a/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h
+++ b/chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h
@@ -27,6 +27,7 @@ class MockAutofillWebDataBackend : public AutofillWebDataBackend {
MOCK_METHOD1(RemoveObserver,
void(AutofillWebDataServiceObserverOnDBSequence* observer));
MOCK_METHOD0(RemoveExpiredFormElements, void());
+ MOCK_METHOD0(CommitChanges, void());
MOCK_METHOD1(NotifyOfAutofillProfileChanged,
void(const AutofillProfileChange& change));
MOCK_METHOD1(NotifyOfCreditCardChanged, void(const CreditCardChange& change));
diff --git a/chromium/components/autofill/core/common/autofill_features.cc b/chromium/components/autofill/core/common/autofill_features.cc
index fbe039a1880..72ad75881ad 100644
--- a/chromium/components/autofill/core/common/autofill_features.cc
+++ b/chromium/components/autofill/core/common/autofill_features.cc
@@ -67,6 +67,10 @@ const base::Feature kAutofillDeleteDisusedAddresses{
const base::Feature kAutofillDeleteDisusedCreditCards{
"AutofillDeleteDisusedCreditCards", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kAutofillDoNotUploadSaveUnsupportedCards{
+ "AutofillDoNotUploadSaveUnsupportedCards",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether the credit card downstream keyboard accessory shows
// the Google Pay logo animation on iOS.
const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS{
@@ -96,6 +100,12 @@ const base::Feature kAutofillEnableCompanyName{
const base::Feature kAutofillEnableIFrameSupportOniOS{
"AutofillEnableIFrameSupportOniOS", base::FEATURE_ENABLED_BY_DEFAULT};
+// When enabled, enable local card migration flow for user who has signed in but
+// has not turned on sync.
+const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser{
+ "AutofillEnableLocalCardMigrationForNonSyncUser",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// When enabled, no local copy of server card will be saved when upload
// succeeds.
const base::Feature kAutofillNoLocalSaveOnUploadSuccess{
@@ -147,6 +157,12 @@ const base::Feature kAutofillLocalCardMigrationShowFeedback{
"AutofillLocalCardMigrationShowFeedback",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Controls whether offering to migrate cards will consider data from the
+// Autofill strike database (new version).
+const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2{
+ "AutofillLocalCardMigrationUsesStrikeSystemV2",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether the manual fallback will be present.
const base::Feature kAutofillManualFallback{"AutofillManualFallback",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -166,6 +182,11 @@ const base::Feature kAutofillPreferServerNamePredictions{
const base::Feature kAutofillPrefilledFields{"AutofillPrefilledFields",
base::FEATURE_ENABLED_BY_DEFAULT};
+// Controls whether Autofill uses server-side validation to ensure that fields
+// with invalid data are not suggested.
+const base::Feature kAutofillProfileServerValidation{
+ "AutofillProfileServerValidation", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether or not a group of fields not enclosed in a form can be
// considered a form. If this is enabled, unowned fields will only constitute
// a form if there are signals to suggest that this might a checkout page.
@@ -249,6 +270,11 @@ const base::Feature kAutofillShowAutocompleteConsoleWarnings{
"AutofillShowAutocompleteConsoleWarnings",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Controls whether suggestions' labels use the full disclosure format to
+// display disambiguation information.
+const base::Feature kAutofillShowFullDisclosureLabel{
+ "AutofillShowFullDisclosureLabel", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls attaching the autofill type predictions to their respective
// element in the DOM.
const base::Feature kAutofillShowTypePredictions{
@@ -259,9 +285,6 @@ const base::Feature kAutofillShowTypePredictions{
const base::Feature kAutofillSkipComparingInferredLabels{
"AutofillSkipComparingInferredLabels", base::FEATURE_DISABLED_BY_DEFAULT};
-const base::Feature kAutofillSuggestInvalidProfileData{
- "AutofillSuggestInvalidProfileData", base::FEATURE_ENABLED_BY_DEFAULT};
-
const base::Feature kAutofillSuppressDisusedAddresses{
"AutofillSuppressDisusedAddresses", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -271,6 +294,11 @@ const base::Feature kAutofillProfileClientValidation{
const base::Feature kAutofillSuppressDisusedCreditCards{
"AutofillSuppressDisusedCreditCards", base::FEATURE_ENABLED_BY_DEFAULT};
+// Controls whether Autofill should search prefixes of all words/tokens when
+// filtering profiles, or only on prefixes of the whole string.
+const base::Feature kAutofillTokenPrefixMatching{
+ "AutofillTokenPrefixMatching", base::FEATURE_DISABLED_BY_DEFAULT};
+
const base::Feature kAutofillUploadThrottling{"AutofillUploadThrottling",
base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chromium/components/autofill/core/common/autofill_features.h b/chromium/components/autofill/core/common/autofill_features.h
index 01e901d9043..cd7525fce26 100644
--- a/chromium/components/autofill/core/common/autofill_features.h
+++ b/chromium/components/autofill/core/common/autofill_features.h
@@ -33,12 +33,14 @@ extern const base::Feature kAutofillCreditCardAssist;
extern const base::Feature kAutofillCreditCardLocalCardMigration;
extern const base::Feature kAutofillDeleteDisusedAddresses;
extern const base::Feature kAutofillDeleteDisusedCreditCards;
+extern const base::Feature kAutofillDoNotUploadSaveUnsupportedCards;
extern const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS;
extern const base::Feature kAutofillDynamicForms;
extern const base::Feature kAutofillEnableAccountWalletStorage;
extern const base::Feature kAutofillEnableAccountWalletStorageUpload;
extern const base::Feature kAutofillEnableCompanyName;
extern const base::Feature kAutofillEnableIFrameSupportOniOS;
+extern const base::Feature kAutofillEnableLocalCardMigrationForNonSyncUser;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
@@ -46,13 +48,15 @@ extern const base::Feature kAutofillGetPaymentsIdentityFromSync;
extern const base::Feature kAutofillImportNonFocusableCreditCardForms;
extern const base::Feature kAutofillKeyboardAccessory;
extern const base::Feature kAutofillLocalCardMigrationShowFeedback;
+extern const base::Feature kAutofillLocalCardMigrationUsesStrikeSystemV2;
extern const base::Feature kAutofillManualFallback;
extern const base::Feature kAutofillManualFallbackPhaseTwo;
extern const base::Feature kAutofillMetadataUploads;
-extern const base::Feature kAutofillPreferServerNamePredictions;
extern const base::Feature kAutofillNoLocalSaveOnUploadSuccess;
extern const base::Feature kAutofillOverrideWithRaterConsensus;
+extern const base::Feature kAutofillPreferServerNamePredictions;
extern const base::Feature kAutofillPrefilledFields;
+extern const base::Feature kAutofillProfileServerValidation;
extern const base::Feature kAutofillRestrictUnownedFieldsToFormlessCheckout;
extern const base::Feature kAutofillRichMetadataQueries;
extern const base::Feature kAutofillSaveCardDialogUnlabeledExpirationDate;
@@ -67,11 +71,12 @@ extern const base::Feature kAutofillServerCommunication;
extern const base::Feature kAutofillSettingsCardTypeSplit;
extern const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms;
extern const base::Feature kAutofillShowAutocompleteConsoleWarnings;
+extern const base::Feature kAutofillShowFullDisclosureLabel;
extern const base::Feature kAutofillShowTypePredictions;
extern const base::Feature kAutofillSkipComparingInferredLabels;
-extern const base::Feature kAutofillSuggestInvalidProfileData;
extern const base::Feature kAutofillSuppressDisusedAddresses;
extern const base::Feature kAutofillSuppressDisusedCreditCards;
+extern const base::Feature kAutofillTokenPrefixMatching;
extern const base::Feature kAutofillUploadThrottling;
extern const base::Feature kAutofillUpstream;
extern const base::Feature kAutofillUpstreamAllowAllEmailDomains;
diff --git a/chromium/components/autofill/core/common/autofill_prefs_unittest.cc b/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
index 1a9e4e0558e..9ce7a569f66 100644
--- a/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_prefs_unittest.cc
@@ -195,7 +195,8 @@ TEST_F(AutofillPrefsTest, WalletSyncTransportPref_CanBeSetAndReadFromJSON) {
std::string output_js;
EXPECT_TRUE(base::JSONWriter::Write(*dictionary, &output_js));
EXPECT_TRUE(dictionary->Equals(
- base::DictionaryValue::From(base::JSONReader::Read(output_js)).get()));
+ base::DictionaryValue::From(base::JSONReader::ReadDeprecated(output_js))
+ .get()));
}
} // namespace prefs
diff --git a/chromium/components/autofill/core/common/autofill_regex_constants.cc b/chromium/components/autofill/core/common/autofill_regex_constants.cc
index d861aa9ea87..c8f46238fe1 100644
--- a/chromium/components/autofill/core/common/autofill_regex_constants.cc
+++ b/chromium/components/autofill/core/common/autofill_regex_constants.cc
@@ -21,15 +21,15 @@ const char kRegionIgnoredRe[] =
const char kAddressNameIgnoredRe[] = "address.*nickname|address.*label";
const char kCompanyRe[] =
"company|business|organization|organisation"
- "|firma|firmenname" // de-DE
- "|empresa" // es
- "|societe|société" // fr-FR
- "|ragione.?sociale" // it-IT
- "|会社" // ja-JP
- "|название.?компании" // ru
- "|单位|公司" // zh-CN
- "|شرکت" // fa
- "|회사|직장"; // ko-KR
+ "|(?<!con)firma|firmenname" // de-DE
+ "|empresa" // es
+ "|societe|société" // fr-FR
+ "|ragione.?sociale" // it-IT
+ "|会社" // ja-JP
+ "|название.?компании" // ru
+ "|单位|公司" // zh-CN
+ "|شرکت" // fa
+ "|회사|직장"; // ko-KR
const char kAddressLine1Re[] =
"^address$|address[_-]?line(one)?|address1|addr1|street"
"|(?:shipping|billing)address$"
@@ -79,11 +79,11 @@ const char kAddressLinesExtraRe[] =
const char kAddressLookupRe[] = "lookup";
const char kCountryRe[] =
"country|countries"
- "|país|pais" // es
- "|国" // ja-JP
- "|国家" // zh-CN
- "|국가|나라" // ko-KR
- "|کشور"; // fa
+ "|país|pais" // es
+ "|(?<!(入|出))国" // ja-JP
+ "|国家" // zh-CN
+ "|국가|나라" // ko-KR
+ "|کشور"; // fa
const char kCountryLocationRe[] = "location";
const char kZipCodeRe[] =
"zip|postal|post.*code|pcode"
@@ -144,6 +144,15 @@ const char kSearchTermRe[] =
"|искать|найти|поиск"; // ru
/////////////////////////////////////////////////////////////////////////////
+// field_price.cc
+/////////////////////////////////////////////////////////////////////////////
+const char kPriceRe[] =
+ "\\bprice\\b|\\brate\\b|\\bcost\\b"
+ "قیمة‎|سعر‎" // ar
+ "قیمت" // fa
+ "|\\bprix\\b|\\bcoût\\b|\\bcout\\b|\\btarif\\b"; // fr-CA
+
+/////////////////////////////////////////////////////////////////////////////
// credit_card_field.cc
/////////////////////////////////////////////////////////////////////////////
const char kNameOnCardRe[] =
@@ -243,6 +252,7 @@ const char kDebitCardRe[] = "debit.*card";
const char kEmailRe[] =
"e.?mail"
"|courriel" // fr
+ "|correo.*electr(o|ó)nico" // es-ES
"|メールアドレス" // ja-JP
"|Электронной.?Почты" // ru
"|邮件|邮箱" // zh-CN
@@ -262,7 +272,7 @@ const char kNameRe[] =
"^name|full.?name|your.?name|customer.?name|bill.?name|ship.?name"
"|name.*first.*last|firstandlastname"
"|nombre.*y.*apellidos" // es
- "|^nom" // fr-FR
+ "|^nom(?!bre)" // fr-FR
"|お名前|氏名" // ja-JP
"|^nome" // pt-BR, pt-PT
"|نام.*نام.*خانوادگی" // fa
@@ -286,11 +296,15 @@ const char kMiddleInitialRe[] = "middle.*initial|m\\.i\\.|mi$|\\bmi\\b";
const char kMiddleNameRe[] =
"middle.*name|mname|middle$"
"|apellido.?materno|lastlastname"; // es
+
+// TODO(crbug.com/928851): Revisit "morada" from pt-PT as it means address and
+// not "last name", and "surename" in pt-PT as it's not Portuguese (or any
+// language?).
const char kLastNameRe[] =
"last.*name|lname|surname|last$|secondname|family.*name"
"|nachname" // de-DE
- "|apellido" // es
- "|famille|^nom" // fr-FR
+ "|apellidos?" // es
+ "|famille|^nom(?!bre)" // fr-FR
"|cognome" // it-IT
"|姓" // ja-JP
"|morada|apelidos|surename|sobrenome" // pt-BR, pt-PT
@@ -329,6 +343,28 @@ const char kPhoneExtensionRe[] =
"|ramal"; // pt-BR, pt-PT
/////////////////////////////////////////////////////////////////////////////
+// travel_field.cc
+/////////////////////////////////////////////////////////////////////////////
+
+const char kPassportRe[] =
+ "document.*number|passport" // en-US
+ "|passeport" // fr-FR
+ "|numero.*documento|pasaporte" // es-ES
+ "|書類"; // ja-JP
+const char kTravelOriginRe[] =
+ "point.*of.*entry|arrival" // en-US
+ "|punto.*internaci(o|ó)n|fecha.*llegada" // es-ES
+ "|入国"; // ja-JP
+const char kTravelDestinationRe[] =
+ "departure" // en-US
+ "|fecha.*salida|destino" // es-ES
+ "|出国"; // ja-JP
+const char kFlightRe[] =
+ "airline|flight" // en-US
+ "|aerol(i|í)nea|n(u|ú)mero.*vuelo" // es-ES
+ "|便名|航空会社"; // ja-JP
+
+/////////////////////////////////////////////////////////////////////////////
// validation.cc
/////////////////////////////////////////////////////////////////////////////
const char kUPIVirtualPaymentAddressRe[] =
diff --git a/chromium/components/autofill/core/common/autofill_regex_constants.h b/chromium/components/autofill/core/common/autofill_regex_constants.h
index bcb18d1cda8..870a800c58f 100644
--- a/chromium/components/autofill/core/common/autofill_regex_constants.h
+++ b/chromium/components/autofill/core/common/autofill_regex_constants.h
@@ -56,6 +56,11 @@ extern const char kPhonePrefixRe[];
extern const char kPhoneSuffixRe[];
extern const char kPhoneExtensionRe[];
extern const char kSearchTermRe[];
+extern const char kPassportRe[];
+extern const char kTravelOriginRe[];
+extern const char kTravelDestinationRe[];
+extern const char kFlightRe[];
+extern const char kPriceRe[];
// Used to match field data that might be a UPI Virtual Payment Address.
// See:
diff --git a/chromium/components/autofill/core/common/autofill_regexes_unittest.cc b/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
index 4b0820d5f2a..4201bceef30 100644
--- a/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_regexes_unittest.cc
@@ -32,23 +32,23 @@ struct InputPatternTestCase {
ASCIIToUTF16(test_case.pattern)));
}
- INSTANTIATE_TEST_CASE_P(AutofillRegexes,
- PositiveSampleTest,
- testing::Values(
- // Empty pattern
- InputPatternTestCase{"", ""},
- InputPatternTestCase{
- "Look, ma' -- a non-empty string!", ""},
- // Substring
- InputPatternTestCase{"string", "tri"},
- // Substring at beginning
- InputPatternTestCase{"string", "str"},
- InputPatternTestCase{"string", "^str"},
- // Substring at end
- InputPatternTestCase{"string", "ring"},
- InputPatternTestCase{"string", "ring$"},
- // Case-insensitive
- InputPatternTestCase{"StRiNg", "string"}));
+ INSTANTIATE_TEST_SUITE_P(AutofillRegexes,
+ PositiveSampleTest,
+ testing::Values(
+ // Empty pattern
+ InputPatternTestCase{"", ""},
+ InputPatternTestCase{
+ "Look, ma' -- a non-empty string!", ""},
+ // Substring
+ InputPatternTestCase{"string", "tri"},
+ // Substring at beginning
+ InputPatternTestCase{"string", "str"},
+ InputPatternTestCase{"string", "^str"},
+ // Substring at end
+ InputPatternTestCase{"string", "ring"},
+ InputPatternTestCase{"string", "ring$"},
+ // Case-insensitive
+ InputPatternTestCase{"StRiNg", "string"}));
class NegativeSampleTest
: public testing::TestWithParam<InputPatternTestCase> {};
@@ -61,20 +61,20 @@ struct InputPatternTestCase {
ASCIIToUTF16(test_case.pattern)));
}
-INSTANTIATE_TEST_CASE_P(AutofillRegexes,
- NegativeSampleTest,
- testing::Values(
- // Empty string
- InputPatternTestCase{
- "", "Look, ma' -- a non-empty pattern!"},
- // Substring
- InputPatternTestCase{"string", "trn"},
- // Substring at beginning
- InputPatternTestCase{"string", " str"},
- InputPatternTestCase{"string", "^tri"},
- // Substring at end
- InputPatternTestCase{"string", "ring "},
- InputPatternTestCase{"string", "rin$"}));
+INSTANTIATE_TEST_SUITE_P(AutofillRegexes,
+ NegativeSampleTest,
+ testing::Values(
+ // Empty string
+ InputPatternTestCase{
+ "", "Look, ma' -- a non-empty pattern!"},
+ // Substring
+ InputPatternTestCase{"string", "trn"},
+ // Substring at beginning
+ InputPatternTestCase{"string", " str"},
+ InputPatternTestCase{"string", "^tri"},
+ // Substring at end
+ InputPatternTestCase{"string", "ring "},
+ InputPatternTestCase{"string", "rin$"}));
struct InputTestCase {
const char* const input;
@@ -90,7 +90,7 @@ struct InputTestCase {
EXPECT_TRUE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
- INSTANTIATE_TEST_CASE_P(
+ INSTANTIATE_TEST_SUITE_P(
AutofillRegexes,
ExpirationDate2DigitYearPositive,
testing::Values(InputTestCase{"mm / yy"},
@@ -124,7 +124,7 @@ struct InputTestCase {
EXPECT_FALSE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
- INSTANTIATE_TEST_CASE_P(
+ INSTANTIATE_TEST_SUITE_P(
AutofillRegexes,
ExpirationDate2DigitYearNegative,
testing::Values(InputTestCase{""},
@@ -164,30 +164,30 @@ struct InputTestCase {
EXPECT_TRUE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
- INSTANTIATE_TEST_CASE_P(AutofillRegexes,
- ExpirationDate4DigitYearPositive,
- testing::Values(
- // Simple four year cases
- InputTestCase{"mm / yyyy"},
- InputTestCase{"mm/ yyyy"},
- InputTestCase{"mm /yyyy"},
- InputTestCase{"mm/yyyy"},
- InputTestCase{"mm - yyyy"},
- InputTestCase{"mm- yyyy"},
- InputTestCase{"mm -yyyy"},
- InputTestCase{"mm-yyyy"},
- InputTestCase{"mmyyyy"},
- // Complex four year cases
- InputTestCase{"Expiration Date (MM / YYYY)"},
- InputTestCase{"Expiration Date (MM/YYYY)"},
- InputTestCase{"Expiration Date (MM - YYYY)"},
- InputTestCase{"Expiration Date (MM-YYYY)"},
- InputTestCase{"Expiration Date MM / YYYY"},
- InputTestCase{"Expiration Date MM/YYYY"},
- InputTestCase{"Expiration Date MM - YYYY"},
- InputTestCase{"Expiration Date MM-YYYY"},
- InputTestCase{"expiration date yyyy"},
- InputTestCase{"Exp Date (MM / YYYY)"}));
+ INSTANTIATE_TEST_SUITE_P(AutofillRegexes,
+ ExpirationDate4DigitYearPositive,
+ testing::Values(
+ // Simple four year cases
+ InputTestCase{"mm / yyyy"},
+ InputTestCase{"mm/ yyyy"},
+ InputTestCase{"mm /yyyy"},
+ InputTestCase{"mm/yyyy"},
+ InputTestCase{"mm - yyyy"},
+ InputTestCase{"mm- yyyy"},
+ InputTestCase{"mm -yyyy"},
+ InputTestCase{"mm-yyyy"},
+ InputTestCase{"mmyyyy"},
+ // Complex four year cases
+ InputTestCase{"Expiration Date (MM / YYYY)"},
+ InputTestCase{"Expiration Date (MM/YYYY)"},
+ InputTestCase{"Expiration Date (MM - YYYY)"},
+ InputTestCase{"Expiration Date (MM-YYYY)"},
+ InputTestCase{"Expiration Date MM / YYYY"},
+ InputTestCase{"Expiration Date MM/YYYY"},
+ InputTestCase{"Expiration Date MM - YYYY"},
+ InputTestCase{"Expiration Date MM-YYYY"},
+ InputTestCase{"expiration date yyyy"},
+ InputTestCase{"Exp Date (MM / YYYY)"}));
class ExpirationDate4DigitYearNegative
: public testing::TestWithParam<InputTestCase> {};
@@ -199,7 +199,7 @@ struct InputTestCase {
EXPECT_FALSE(MatchesPattern(ASCIIToUTF16(test_case.input), pattern));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillRegexes,
ExpirationDate4DigitYearNegative,
testing::Values(InputTestCase{""},
diff --git a/chromium/components/autofill/core/common/autofill_switches.cc b/chromium/components/autofill/core/common/autofill_switches.cc
index 4bb9f632105..cf0334180cf 100644
--- a/chromium/components/autofill/core/common/autofill_switches.cc
+++ b/chromium/components/autofill/core/common/autofill_switches.cc
@@ -22,6 +22,11 @@ const char kAutofillServerURL[] = "autofill-server-url";
const char kAutofillMetadataUploadEncoding[] =
"autofill-metadata-upload-encoding";
+// The number of days after which to reset the registry of autofill events for
+// which an upload has been sent.
+const char kAutofillUploadThrottlingPeriodInDays[] =
+ "autofill-upload-throttling-period-in-days";
+
// Force hiding the local save checkbox in the autofill dialog box for getting
// the full credit card number for a wallet card. The card will never be stored
// locally.
@@ -33,10 +38,6 @@ const char kDisableOfferStoreUnmaskedWalletCards[] =
const char kEnableOfferStoreUnmaskedWalletCards[] =
"enable-offer-store-unmasked-wallet-cards";
-// Enables suggestions with substring matching instead of prefix matching.
-const char kEnableSuggestionsWithSubstringMatch[] =
- "enable-suggestions-with-substring-match";
-
// Ignores autocomplete="off" for Autofill data (profiles + credit cards).
const char kIgnoreAutocompleteOffForAutofill[] =
"ignore-autocomplete-off-autofill";
@@ -48,7 +49,7 @@ const char kShowAutofillTypePredictions[] = "show-autofill-type-predictions";
const char kShowAutofillSignatures[] = "show-autofill-signatures";
// Use the sandbox Online Wallet service URL (for developer testing).
-const char kWalletServiceUseSandbox[] = "wallet-service-use-sandbox";
+const char kWalletServiceUseSandbox[] = "wallet-service-use-sandbox";
} // namespace switches
} // namespace autofill
diff --git a/chromium/components/autofill/core/common/autofill_switches.h b/chromium/components/autofill/core/common/autofill_switches.h
index 2f58a2d51a7..0e6bffefcc7 100644
--- a/chromium/components/autofill/core/common/autofill_switches.h
+++ b/chromium/components/autofill/core/common/autofill_switches.h
@@ -15,9 +15,9 @@ namespace switches {
extern const char kAutofillAPIKey[];
extern const char kAutofillServerURL[];
extern const char kAutofillMetadataUploadEncoding[];
+extern const char kAutofillUploadThrottlingPeriodInDays[];
extern const char kDisableOfferStoreUnmaskedWalletCards[];
extern const char kEnableOfferStoreUnmaskedWalletCards[];
-extern const char kEnableSuggestionsWithSubstringMatch[];
extern const char kIgnoreAutocompleteOffForAutofill[];
extern const char kShowAutofillTypePredictions[];
extern const char kShowAutofillSignatures[];
diff --git a/chromium/components/autofill/core/common/autofill_util.cc b/chromium/components/autofill/core/common/autofill_util.cc
index 0191e664fe3..adf79a52ee2 100644
--- a/chromium/components/autofill/core/common/autofill_util.cc
+++ b/chromium/components/autofill/core/common/autofill_util.cc
@@ -51,8 +51,7 @@ struct Compare : base::CaseInsensitiveCompareASCII<Char> {
} // namespace
bool IsFeatureSubstringMatchEnabled() {
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ return base::FeatureList::IsEnabled(features::kAutofillTokenPrefixMatching);
}
bool IsShowAutofillSignaturesEnabled() {
diff --git a/chromium/components/autofill/core/common/autofill_util_unittest.cc b/chromium/components/autofill/core/common/autofill_util_unittest.cc
index 6a59b0d618f..4f1430a88bd 100644
--- a/chromium/components/autofill/core/common/autofill_util_unittest.cc
+++ b/chromium/components/autofill/core/common/autofill_util_unittest.cc
@@ -9,7 +9,8 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/common/autofill_switches.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
@@ -27,14 +28,19 @@ class FieldIsTokenBoundarySubstringCaseTest
TEST_P(FieldIsTokenBoundarySubstringCaseTest,
FieldIsSuggestionSubstringStartingOnTokenBoundary) {
- // FieldIsSuggestionSubstringStartingOnTokenBoundary should not work yet
- // without a flag.
- EXPECT_FALSE(FieldIsSuggestionSubstringStartingOnTokenBoundary(
- base::ASCIIToUTF16("ab@cd.b"), base::ASCIIToUTF16("b"), false));
+ {
+ base::test::ScopedFeatureList features_disabled;
+ features_disabled.InitAndDisableFeature(
+ features::kAutofillTokenPrefixMatching);
- // Token matching is currently behind a flag.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableSuggestionsWithSubstringMatch);
+ // FieldIsSuggestionSubstringStartingOnTokenBoundary should not work yet
+ // without a flag.
+ EXPECT_FALSE(FieldIsSuggestionSubstringStartingOnTokenBoundary(
+ base::ASCIIToUTF16("ab@cd.b"), base::ASCIIToUTF16("b"), false));
+ }
+
+ base::test::ScopedFeatureList features_enabled;
+ features_enabled.InitAndEnableFeature(features::kAutofillTokenPrefixMatching);
auto test_case = GetParam();
SCOPED_TRACE(testing::Message()
@@ -49,7 +55,7 @@ TEST_P(FieldIsTokenBoundarySubstringCaseTest,
test_case.case_sensitive));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
FieldIsTokenBoundarySubstringCaseTest,
testing::Values(
@@ -91,7 +97,7 @@ TEST_P(PrefixEndingOnTokenBoundaryTest, IsPrefixOfEmailEndingWithAtSign) {
base::ASCIIToUTF16(test_case.field_contents)));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
PrefixEndingOnTokenBoundaryTest,
testing::Values(AtSignPrefixCase{"ab@cd.b", "a", false},
@@ -136,7 +142,7 @@ TEST_P(GetTextSelectionStartTest, GetTextSelectionStart) {
test_case.case_sensitive));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
GetTextSelectionStartTest,
testing::Values(
@@ -172,7 +178,7 @@ TEST_P(LowercaseAndTokenizeAttributeStringTest,
LowercaseAndTokenizeAttributeString(test_case.attribute));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
AutofillUtilTest,
LowercaseAndTokenizeAttributeStringTest,
testing::Values(
diff --git a/chromium/components/autofill/core/common/form_field_data.h b/chromium/components/autofill/core/common/form_field_data.h
index 8b67278ba80..cfe44ba6eaa 100644
--- a/chromium/components/autofill/core/common/form_field_data.h
+++ b/chromium/components/autofill/core/common/form_field_data.h
@@ -108,7 +108,7 @@ struct FormFieldData {
// Returns true if the field is visible to the user.
bool IsVisible() const {
return is_focusable && role != ROLE_ATTRIBUTE_PRESENTATION;
- };
+ }
// Note: operator==() performs a full-field-comparison(byte by byte), this is
// different from SameFieldAs(), which ignores comparison for those "values"
diff --git a/chromium/components/autofill/core/common/password_generation_util.cc b/chromium/components/autofill/core/common/password_generation_util.cc
index c040a3ea40a..1e5af2bafc9 100644
--- a/chromium/components/autofill/core/common/password_generation_util.cc
+++ b/chromium/components/autofill/core/common/password_generation_util.cc
@@ -13,15 +13,6 @@
namespace autofill {
namespace password_generation {
-PasswordGenerationActions::PasswordGenerationActions()
- : learn_more_visited(false),
- password_accepted(false),
- password_edited(false),
- password_regenerated(false) {
-}
-
-PasswordGenerationActions::~PasswordGenerationActions() {
-}
PasswordGenerationUIData::PasswordGenerationUIData(
const gfx::RectF& bounds,
@@ -39,20 +30,6 @@ PasswordGenerationUIData::PasswordGenerationUIData() = default;
PasswordGenerationUIData::~PasswordGenerationUIData() = default;
-void LogUserActions(PasswordGenerationActions actions) {
- UserAction action = IGNORE_FEATURE;
- if (actions.password_accepted) {
- if (actions.password_edited)
- action = ACCEPT_AFTER_EDITING;
- else
- action = ACCEPT_ORIGINAL_PASSWORD;
- } else if (actions.learn_more_visited) {
- action = LEARN_MORE;
- }
- UMA_HISTOGRAM_ENUMERATION("PasswordGeneration.UserActions",
- action, ACTION_ENUM_COUNT);
-}
-
void LogPasswordGenerationEvent(PasswordGenerationEvent event) {
UMA_HISTOGRAM_ENUMERATION("PasswordGeneration.Event",
event, EVENT_ENUM_COUNT);
diff --git a/chromium/components/autofill/core/common/password_generation_util.h b/chromium/components/autofill/core/common/password_generation_util.h
index fa350e93110..b84433a5b21 100644
--- a/chromium/components/autofill/core/common/password_generation_util.h
+++ b/chromium/components/autofill/core/common/password_generation_util.h
@@ -124,33 +124,8 @@ struct PasswordGenerationUIData {
autofill::PasswordForm password_form;
};
-void LogUserActions(PasswordGenerationActions actions);
-
void LogPasswordGenerationEvent(PasswordGenerationEvent event);
-// Enumerates user actions after password generation bubble is shown.
-// These are visible for testing purposes.
-enum UserAction {
- // User closes the bubble without any meaningful actions (e.g. use backspace
- // key, close the bubble, click outside the bubble, etc).
- IGNORE_FEATURE,
-
- // User navigates to the learn more page. Note that in the current
- // implementation this will result in closing the bubble so this action
- // doesn't overlap with the following two actions.
- LEARN_MORE,
-
- // User accepts the generated password without manually editing it (but
- // including changing it through the regenerate button).
- ACCEPT_ORIGINAL_PASSWORD,
-
- // User accepts the gererated password after manually editing it.
- ACCEPT_AFTER_EDITING,
-
- // Number of enum entries, used for UMA histogram reporting macros.
- ACTION_ENUM_COUNT
-};
-
// Returns true if Password Generation is enabled according to the field
// trial result and the flags.
bool IsPasswordGenerationEnabled();
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger.cc b/chromium/components/autofill/core/common/save_password_progress_logger.cc
index de254813971..266a8303a5e 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger.cc
+++ b/chromium/components/autofill/core/common/save_password_progress_logger.cc
@@ -18,7 +18,7 @@
using base::checked_cast;
using base::DictionaryValue;
-using base::UintToString;
+using base::NumberToString;
using base::Value;
namespace autofill {
@@ -72,19 +72,19 @@ void SavePasswordProgressLogger::LogPasswordForm(
ScrubElementID(form.username_element));
if (form.has_renderer_ids) {
log.SetString(GetStringFromID(STRING_USERNAME_ELEMENT_RENDERER_ID),
- UintToString(form.username_element_renderer_id));
+ NumberToString(form.username_element_renderer_id));
}
log.SetString(GetStringFromID(STRING_PASSWORD_ELEMENT),
ScrubElementID(form.password_element));
if (form.has_renderer_ids) {
log.SetString(GetStringFromID(STRING_PASSWORD_ELEMENT_RENDERER_ID),
- UintToString(form.password_element_renderer_id));
+ NumberToString(form.password_element_renderer_id));
}
log.SetString(GetStringFromID(STRING_NEW_PASSWORD_ELEMENT),
ScrubElementID(form.new_password_element));
if (form.has_renderer_ids) {
log.SetString(GetStringFromID(STRING_NEW_PASSWORD_ELEMENT_RENDERER_ID),
- UintToString(form.new_password_element_renderer_id));
+ NumberToString(form.new_password_element_renderer_id));
}
if (!form.confirmation_password_element.empty()) {
log.SetString(GetStringFromID(STRING_CONFIRMATION_PASSWORD_ELEMENT),
@@ -92,7 +92,7 @@ void SavePasswordProgressLogger::LogPasswordForm(
if (form.has_renderer_ids) {
log.SetString(
GetStringFromID(STRING_CONFIRMATION_PASSWORD_ELEMENT_RENDERER_ID),
- UintToString(form.confirmation_password_element_renderer_id));
+ NumberToString(form.confirmation_password_element_renderer_id));
}
}
log.SetBoolean(GetStringFromID(STRING_PASSWORD_GENERATED),
diff --git a/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc b/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc
index a20d11946af..325873f2750 100644
--- a/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc
+++ b/chromium/components/autofill/core/common/save_password_progress_logger_unittest.cc
@@ -40,7 +40,7 @@ class TestLogger : public SavePasswordProgressLogger {
std::string accumulated_log_;
};
-}; // namespace
+} // namespace
TEST(SavePasswordProgressLoggerTest, LogPasswordForm) {
TestLogger logger;
diff --git a/chromium/components/autofill/ios/browser/autofill_agent.mm b/chromium/components/autofill/ios/browser/autofill_agent.mm
index eb8bf0dd088..d6de84b5ce7 100644
--- a/chromium/components/autofill/ios/browser/autofill_agent.mm
+++ b/chromium/components/autofill/ios/browser/autofill_agent.mm
@@ -538,7 +538,7 @@ autofillManagerFromWebState:(web::WebState*)webState
FormSuggestion* suggestion = [FormSuggestion
suggestionWithValue:value
displayDescription:displayDescription
- icon:base::SysUTF16ToNSString(popup_suggestion.icon)
+ icon:base::SysUTF8ToNSString(popup_suggestion.icon)
identifier:popup_suggestion.frontend_id];
// Put "clear form" entry at the front of the suggestions. If
diff --git a/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h b/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h
index d99ed3ec9fe..3265d09b7fe 100644
--- a/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h
+++ b/chromium/components/autofill/ios/browser/autofill_client_ios_bridge.h
@@ -12,7 +12,7 @@
namespace autofill {
class AutofillPopupDelegate;
struct Suggestion;
-};
+}
// Interface used to pipe events from AutofillClientIOS to the embedder.
@protocol AutofillClientIOSBridge
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios.h b/chromium/components/autofill/ios/browser/autofill_driver_ios.h
index f460f3f12c7..5e9408dbb98 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios.h
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios.h
@@ -65,7 +65,7 @@ class AutofillDriverIOS : public AutofillDriver {
const gfx::RectF& bounding_box) override;
bool is_processed() const { return processed_; }
- void set_processed(bool processed) { processed_ = processed; };
+ void set_processed(bool processed) { processed_ = processed; }
protected:
AutofillDriverIOS(
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios.mm b/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
index ce08c746ecd..214164a003d 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios.mm
@@ -107,7 +107,7 @@ void AutofillDriverIOS::SendFormDataToRenderer(
void AutofillDriverIOS::PropagateAutofillPredictions(
const std::vector<autofill::FormStructure*>& forms) {
autofill_manager_.client()->PropagateAutofillPredictions(nullptr, forms);
-};
+}
void AutofillDriverIOS::SendAutofillTypePredictionsToRenderer(
const std::vector<FormStructure*>& forms) {
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h
index 56a6630190e..005468fb616 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.h
@@ -47,11 +47,14 @@ class AutofillDriverIOSWebFrameFactory
web::WebFrame* web_frame);
private:
+ friend class web::WebStateUserData<AutofillDriverIOSWebFrameFactory>;
+
web::WebState* web_state_ = nullptr;
AutofillClient* client_ = nullptr;
id<AutofillDriverIOSBridge> bridge_ = nil;
std::string app_locale_;
AutofillManager::AutofillDownloadManagerState enable_download_manager_;
+ WEB_STATE_USER_DATA_KEY_DECL();
};
// AutofillDriverIOSWebFrame will keep a refcountable AutofillDriverIOS. This is
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm
index 2c4988db611..cc3c6d6e7a4 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webframe.mm
@@ -4,7 +4,7 @@
#include "components/autofill/ios/browser/autofill_driver_ios_webframe.h"
-#include "ios/web/public/web_state/web_state.h"
+#import "ios/web/public/web_state/web_state.h"
namespace autofill {
@@ -101,4 +101,6 @@ AutofillDriverIOSWebFrame::GetRetainableDriver() {
return driver_;
}
+WEB_STATE_USER_DATA_KEY_IMPL(AutofillDriverIOSWebFrameFactory)
+
} // namespace autofill
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h
index 7e3dabd4c62..0da71bf0bce 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.h
@@ -34,6 +34,7 @@ class AutofillDriverIOSWebState
id<AutofillDriverIOSBridge> bridge,
const std::string& app_locale,
AutofillManager::AutofillDownloadManagerState enable_download_manager);
+ WEB_STATE_USER_DATA_KEY_DECL();
};
} // namespace autofill
diff --git a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm
index 0237ae17128..723b4b97f39 100644
--- a/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm
+++ b/chromium/components/autofill/ios/browser/autofill_driver_ios_webstate.mm
@@ -4,7 +4,7 @@
#include "components/autofill/ios/browser/autofill_driver_ios_webstate.h"
-#include "ios/web/public/web_state/web_state.h"
+#import "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
@@ -43,4 +43,6 @@ AutofillDriverIOSWebState::AutofillDriverIOSWebState(
AutofillDriverIOSWebState::~AutofillDriverIOSWebState() {}
+WEB_STATE_USER_DATA_KEY_IMPL(AutofillDriverIOSWebState)
+
} // namespace autofill
diff --git a/chromium/components/autofill/ios/browser/autofill_util.mm b/chromium/components/autofill/ios/browser/autofill_util.mm
index 673b520ecf9..208e29c433a 100644
--- a/chromium/components/autofill/ios/browser/autofill_util.mm
+++ b/chromium/components/autofill/ios/browser/autofill_util.mm
@@ -54,9 +54,10 @@ std::unique_ptr<base::Value> ParseJson(NSString* json_string) {
// Convert JSON string to JSON object |JSONValue|.
int error_code = 0;
std::string error_message;
- std::unique_ptr<base::Value> json_value(base::JSONReader::ReadAndReturnError(
- base::SysNSStringToUTF8(json_string), base::JSON_PARSE_RFC, &error_code,
- &error_message));
+ std::unique_ptr<base::Value> json_value(
+ base::JSONReader::ReadAndReturnErrorDeprecated(
+ base::SysNSStringToUTF8(json_string), base::JSON_PARSE_RFC,
+ &error_code, &error_message));
if (error_code)
return nullptr;
diff --git a/chromium/components/autofill/ios/browser/js_suggestion_manager.mm b/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
index 4b6c3f2e814..39f77b5c090 100644
--- a/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
+++ b/chromium/components/autofill/ios/browser/js_suggestion_manager.mm
@@ -6,6 +6,7 @@
#include <vector>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/format_macros.h"
#include "base/json/string_escape.h"
diff --git a/chromium/components/autofill/ios/browser/resources/autofill_controller.js b/chromium/components/autofill/ios/browser/resources/autofill_controller.js
index ec5477b5d45..2172b64182e 100644
--- a/chromium/components/autofill/ios/browser/resources/autofill_controller.js
+++ b/chromium/components/autofill/ios/browser/resources/autofill_controller.js
@@ -256,7 +256,7 @@ __gCrWeb.autofill['fillForm'] = function(data, forceFillFieldIdentifier) {
if (!__gCrWeb.autofill.styleInjected) {
var style = document.createElement('style');
style.textContent = '[chrome-autofilled] {' +
- 'background-color:#FAFFBD !important;' +
+ 'background-color:#E8F0FE !important;' +
'background-image:none !important;' +
'color:#000000 !important;' +
'}';
diff --git a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h
index 3af1db68bab..714fc282c4d 100644
--- a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h
+++ b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.h
@@ -33,6 +33,7 @@ class FormActivityTabHelper
private:
friend class web::WebStateUserData<FormActivityTabHelper>;
+
// TestFormActivityTabHelper can be used by tests that want to simulate form
// events without loading page and executing JavaScript.
// To trigger events, TestFormActivityTabHelper will access |observer_|.
@@ -69,6 +70,8 @@ class FormActivityTabHelper
// The observers.
base::ObserverList<FormActivityObserver>::Unchecked observers_;
+ WEB_STATE_USER_DATA_KEY_DECL();
+
DISALLOW_COPY_AND_ASSIGN(FormActivityTabHelper);
};
diff --git a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm
index ed04da751eb..ba38e373c5b 100644
--- a/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm
+++ b/chromium/components/autofill/ios/form_util/form_activity_tab_helper.mm
@@ -6,6 +6,7 @@
#import <Foundation/Foundation.h>
+#include "base/bind.h"
#include "base/values.h"
#include "components/autofill/ios/form_util/form_activity_observer.h"
#include "components/autofill/ios/form_util/form_activity_params.h"
@@ -144,4 +145,6 @@ void FormActivityTabHelper::WebStateDestroyed(web::WebState* web_state) {
web_state_ = nullptr;
}
+WEB_STATE_USER_DATA_KEY_IMPL(FormActivityTabHelper)
+
} // namespace autofill