summaryrefslogtreecommitdiff
path: root/chromium/components/autofill/core/browser
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 11:40:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 12:42:11 +0000
commit5d87695f37678f96492b258bbab36486c59866b4 (patch)
treebe9783bbaf04fb930c4d74ca9c00b5e7954c8bc6 /chromium/components/autofill/core/browser
parent6c11fb357ec39bf087b8b632e2b1e375aef1b38b (diff)
downloadqtwebengine-chromium-5d87695f37678f96492b258bbab36486c59866b4.tar.gz
BASELINE: Update Chromium to 75.0.3770.56
Change-Id: I86d2007fd27a45d5797eee06f4c9369b8b50ac4f Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/autofill/core/browser')
-rw-r--r--chromium/components/autofill/core/browser/BUILD.gn198
-rw-r--r--chromium/components/autofill/core/browser/DEPS1
-rw-r--r--chromium/components/autofill/core/browser/OWNERS3
-rw-r--r--chromium/components/autofill/core/browser/address_contact_form_label_formatter.cc61
-rw-r--r--chromium/components/autofill/core/browser/address_contact_form_label_formatter.h52
-rw-r--r--chromium/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc510
-rw-r--r--chromium/components/autofill/core/browser/address_email_form_label_formatter.cc61
-rw-r--r--chromium/components/autofill/core/browser/address_email_form_label_formatter.h52
-rw-r--r--chromium/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc332
-rw-r--r--chromium/components/autofill/core/browser/address_form_label_formatter.cc33
-rw-r--r--chromium/components/autofill/core/browser/address_form_label_formatter.h14
-rw-r--r--chromium/components/autofill/core/browser/address_form_label_formatter_unittest.cc191
-rw-r--r--chromium/components/autofill/core/browser/address_phone_form_label_formatter.cc60
-rw-r--r--chromium/components/autofill/core/browser/address_phone_form_label_formatter.h51
-rw-r--r--chromium/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc325
-rw-r--r--chromium/components/autofill/core/browser/autocomplete_history_manager.cc5
-rw-r--r--chromium/components/autofill/core/browser/autocomplete_history_manager_unittest.cc35
-rw-r--r--chromium/components/autofill/core/browser/autofill_assistant_unittest.cc12
-rw-r--r--chromium/components/autofill/core/browser/autofill_client.h8
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model.cc5
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_model.h12
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_util.cc48
-rw-r--r--chromium/components/autofill/core/browser/autofill_data_util.h34
-rw-r--r--chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc6
-rw-r--r--chromium/components/autofill/core/browser/autofill_experiments.cc161
-rw-r--r--chromium/components/autofill/core/browser/autofill_experiments.h42
-rw-r--r--chromium/components/autofill/core/browser/autofill_experiments_unittest.cc233
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate.cc3
-rw-r--r--chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc1
-rw-r--r--chromium/components/autofill/core/browser/autofill_handler.cc32
-rw-r--r--chromium/components/autofill/core/browser/autofill_handler.h16
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.cc14
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager.h2
-rw-r--r--chromium/components/autofill/core/browser/autofill_manager_unittest.cc449
-rw-r--r--chromium/components/autofill/core/browser/autofill_merge_unittest.cc2
-rw-r--r--chromium/components/autofill/core/browser/autofill_metadata.cc7
-rw-r--r--chromium/components/autofill/core/browser/autofill_metadata.h4
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.cc33
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics.h35
-rw-r--r--chromium/components/autofill/core/browser/autofill_metrics_unittest.cc292
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.cc41
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile.h11
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_comparator_unittest.cc25
-rw-r--r--chromium/components/autofill/core/browser/autofill_profile_unittest.cc32
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.cc14
-rw-r--r--chromium/components/autofill/core/browser/autofill_test_utils.h9
-rw-r--r--chromium/components/autofill/core/browser/autofill_type.cc4
-rw-r--r--chromium/components/autofill/core/browser/contact_form_label_formatter.cc57
-rw-r--r--chromium/components/autofill/core/browser/contact_form_label_formatter.h26
-rw-r--r--chromium/components/autofill/core/browser/contact_form_label_formatter_unittest.cc306
-rw-r--r--chromium/components/autofill/core/browser/contact_info.cc23
-rw-r--r--chromium/components/autofill/core/browser/contact_info.h6
-rw-r--r--chromium/components/autofill/core/browser/contact_info_unittest.cc95
-rw-r--r--chromium/components/autofill/core/browser/field_types.h5
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer.cc14
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer.h7
-rw-r--r--chromium/components/autofill/core/browser/form_data_importer_unittest.cc157
-rw-r--r--chromium/components/autofill/core/browser/form_structure.cc119
-rw-r--r--chromium/components/autofill/core/browser/form_structure.h44
-rw-r--r--chromium/components/autofill/core/browser/form_structure_unittest.cc436
-rw-r--r--chromium/components/autofill/core/browser/label_formatter.cc95
-rw-r--r--chromium/components/autofill/core/browser/label_formatter.h57
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_unittest.cc24
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils.cc282
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils.h165
-rw-r--r--chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc223
-rw-r--r--chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc61
-rw-r--r--chromium/components/autofill/core/browser/metrics/address_form_event_logger.h10
-rw-r--r--chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.cc10
-rw-r--r--chromium/components/autofill/core/browser/metrics/credit_card_form_event_logger.h9
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc16
-rw-r--r--chromium/components/autofill/core/browser/metrics/form_event_logger_base.h13
-rw-r--r--chromium/components/autofill/core/browser/password_generator.cc222
-rw-r--r--chromium/components/autofill/core/browser/password_generator.h30
-rw-r--r--chromium/components/autofill/core/browser/password_generator_fips181.cc124
-rw-r--r--chromium/components/autofill/core/browser/password_generator_fips181.h62
-rw-r--r--chromium/components/autofill/core/browser/password_generator_fips181_fuzzer.cc47
-rw-r--r--chromium/components/autofill/core/browser/password_generator_fips181_unittest.cc117
-rw-r--r--chromium/components/autofill/core/browser/password_generator_proto_fuzzer.cc15
-rw-r--r--chromium/components/autofill/core/browser/password_generator_unittest.cc273
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_fetcher.h41
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc315
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.h143
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_fetcher_unittest.cc343
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_printer.cc48
-rw-r--r--chromium/components/autofill/core/browser/password_requirements_spec_printer.h23
-rw-r--r--chromium/components/autofill/core/browser/payments/OWNERS1
-rw-r--r--chromium/components/autofill/core/browser/payments/account_info_getter.h (renamed from chromium/components/autofill/core/browser/account_info_getter.h)6
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.cc (renamed from chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc)3
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.h (renamed from chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h)6
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.cc (renamed from chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc)4
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h (renamed from chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h)8
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_mobile.h (renamed from chromium/components/autofill/core/browser/autofill_save_card_infobar_mobile.h)6
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller.cc (renamed from chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc)29
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller.h (renamed from chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h)17
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller_unittest.cc (renamed from chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc)56
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.cc (renamed from chromium/components/autofill/core/browser/autofill_wallet_model_type_controller.cc)59
-rw-r--r--chromium/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h (renamed from chromium/components/autofill/core/browser/autofill_wallet_model_type_controller.h)17
-rw-r--r--chromium/components/autofill/core/browser/payments/card_unmask_delegate.cc (renamed from chromium/components/autofill/core/browser/card_unmask_delegate.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/card_unmask_delegate.h (renamed from chromium/components/autofill/core/browser/card_unmask_delegate.h)6
-rw-r--r--chromium/components/autofill/core/browser/payments/credit_card_save_manager.cc (renamed from chromium/components/autofill/core/browser/credit_card_save_manager.cc)38
-rw-r--r--chromium/components/autofill/core/browser/payments/credit_card_save_manager.h (renamed from chromium/components/autofill/core/browser/credit_card_save_manager.h)24
-rw-r--r--chromium/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc (renamed from chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc)188
-rw-r--r--chromium/components/autofill/core/browser/payments/credit_card_save_strike_database.cc (renamed from chromium/components/autofill/core/browser/credit_card_save_strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/credit_card_save_strike_database.h (renamed from chromium/components/autofill/core/browser/credit_card_save_strike_database.h)10
-rw-r--r--chromium/components/autofill/core/browser/payments/full_card_request.cc3
-rw-r--r--chromium/components/autofill/core/browser/payments/full_card_request.h2
-rw-r--r--chromium/components/autofill/core/browser/payments/full_card_request_unittest.cc13
-rw-r--r--chromium/components/autofill/core/browser/payments/legacy_strike_database.cc (renamed from chromium/components/autofill/core/browser/legacy_strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/legacy_strike_database.h (renamed from chromium/components/autofill/core/browser/legacy_strike_database.h)6
-rw-r--r--chromium/components/autofill/core/browser/payments/legacy_strike_database_unittest.cc (renamed from chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/legal_message_line.cc (renamed from chromium/components/autofill/core/browser/legal_message_line.cc)63
-rw-r--r--chromium/components/autofill/core/browser/payments/legal_message_line.h (renamed from chromium/components/autofill/core/browser/legal_message_line.h)14
-rw-r--r--chromium/components/autofill/core/browser/payments/legal_message_line_unittest.cc (renamed from chromium/components/autofill/core/browser/legal_message_line_unittest.cc)13
-rw-r--r--chromium/components/autofill/core/browser/payments/local_card_migration_manager.cc (renamed from chromium/components/autofill/core/browser/local_card_migration_manager.cc)45
-rw-r--r--chromium/components/autofill/core/browser/payments/local_card_migration_manager.h (renamed from chromium/components/autofill/core/browser/local_card_migration_manager.h)8
-rw-r--r--chromium/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc (renamed from chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc)250
-rw-r--r--chromium/components/autofill/core/browser/payments/local_card_migration_strike_database.cc (renamed from chromium/components/autofill/core/browser/local_card_migration_strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/local_card_migration_strike_database.h (renamed from chromium/components/autofill/core/browser/local_card_migration_strike_database.h)10
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.cc154
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client.h16
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_client_unittest.cc185
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_request.h2
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_service_url.cc24
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_service_url.h11
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_service_url_unittest.cc17
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_util.cc59
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_util.h6
-rw-r--r--chromium/components/autofill/core/browser/payments/payments_util_unittest.cc69
-rw-r--r--chromium/components/autofill/core/browser/payments/risk_data_loader.h (renamed from chromium/components/autofill/core/browser/risk_data_loader.h)6
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database.cc (renamed from chromium/components/autofill/core/browser/strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database.h (renamed from chromium/components/autofill/core/browser/strike_database.h)6
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database_integrator_base.cc (renamed from chromium/components/autofill/core/browser/strike_database_integrator_base.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database_integrator_base.h (renamed from chromium/components/autofill/core/browser/strike_database_integrator_base.h)8
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database.cc (renamed from chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database.h (renamed from chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h)10
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database_unittest.cc (renamed from chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc)6
-rw-r--r--chromium/components/autofill/core/browser/payments/strike_database_unittest.cc (renamed from chromium/components/autofill/core/browser/strike_database_unittest.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/test_credit_card_save_manager.cc (renamed from chromium/components/autofill/core/browser/test_credit_card_save_manager.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/test_credit_card_save_manager.h (renamed from chromium/components/autofill/core/browser/test_credit_card_save_manager.h)8
-rw-r--r--chromium/components/autofill/core/browser/payments/test_credit_card_save_strike_database.cc (renamed from chromium/components/autofill/core/browser/test_credit_card_save_strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/test_credit_card_save_strike_database.h (renamed from chromium/components/autofill/core/browser/test_credit_card_save_strike_database.h)8
-rw-r--r--chromium/components/autofill/core/browser/payments/test_legacy_strike_database.cc (renamed from chromium/components/autofill/core/browser/test_legacy_strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/test_legacy_strike_database.h (renamed from chromium/components/autofill/core/browser/test_legacy_strike_database.h)8
-rw-r--r--chromium/components/autofill/core/browser/payments/test_local_card_migration_manager.cc (renamed from chromium/components/autofill/core/browser/test_local_card_migration_manager.cc)11
-rw-r--r--chromium/components/autofill/core/browser/payments/test_local_card_migration_manager.h (renamed from chromium/components/autofill/core/browser/test_local_card_migration_manager.h)8
-rw-r--r--chromium/components/autofill/core/browser/payments/test_payments_client.cc2
-rw-r--r--chromium/components/autofill/core/browser/payments/test_payments_client.h1
-rw-r--r--chromium/components/autofill/core/browser/payments/test_strike_database.cc (renamed from chromium/components/autofill/core/browser/test_strike_database.cc)2
-rw-r--r--chromium/components/autofill/core/browser/payments/test_strike_database.h (renamed from chromium/components/autofill/core/browser/test_strike_database.h)8
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.cc384
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager.h34
-rw-r--r--chromium/components/autofill/core/browser/personal_data_manager_unittest.cc350
-rw-r--r--chromium/components/autofill/core/browser/phone_number.cc2
-rw-r--r--chromium/components/autofill/core/browser/phone_number.h4
-rw-r--r--chromium/components/autofill/core/browser/phone_number_i18n.cc2
-rw-r--r--chromium/components/autofill/core/browser/proto/api_v1.proto4
-rw-r--r--chromium/components/autofill/core/browser/proto/legacy_proto_bridge.cc1
-rw-r--r--chromium/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc4
-rw-r--r--chromium/components/autofill/core/browser/proto/server.proto9
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection.cc36
-rw-r--r--chromium/components/autofill/core/browser/suggestion_selection.h9
-rw-r--r--chromium/components/autofill/core/browser/sync_utils.h5
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.cc2
-rw-r--r--chromium/components/autofill/core/browser/test_autofill_client.h4
-rw-r--r--chromium/components/autofill/core/browser/test_personal_data_manager.cc8
-rw-r--r--chromium/components/autofill/core/browser/test_personal_data_manager.h2
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/DEPS (renamed from chromium/components/autofill/core/browser/ui/DEPS)0
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/OWNERS1
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_view_delegate_mobile.cc (renamed from chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc)2
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_view_delegate_mobile.h (renamed from chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h)6
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_name_fix_flow_view_delegate_mobile.cc (renamed from chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc)2
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_name_fix_flow_view_delegate_mobile.h (renamed from chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.h)7
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h (renamed from chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller.h)6
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc (renamed from chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc)20
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h (renamed from chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h)15
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc (renamed from chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc)54
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_view.h (renamed from chromium/components/autofill/core/browser/ui/card_unmask_prompt_view.h)6
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h (renamed from chromium/components/autofill/core/browser/ui/local_card_migration_bubble_controller.h)6
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h (renamed from chromium/components/autofill/core/browser/ui/local_card_migration_dialog_controller.h)8
-rw-r--r--chromium/components/autofill/core/browser/ui/payments/save_card_bubble_controller.h (renamed from chromium/components/autofill/core/browser/ui/save_card_bubble_controller.h)8
-rw-r--r--chromium/components/autofill/core/browser/webdata/OWNERS6
-rw-r--r--chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc22
-rw-r--r--chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc101
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_change.h23
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc24
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h7
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc68
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc110
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc39
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc7
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc83
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.h4
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc22
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table.cc28
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table.h4
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc70
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc213
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h12
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc443
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc63
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h3
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service_unittest.cc22
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc65
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h19
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc39
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc6
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata.h144
-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.cc62
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h13
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc264
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.h27
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc26
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h128
-rw-r--r--chromium/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h9
-rw-r--r--chromium/components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h1
-rw-r--r--chromium/components/autofill/core/browser/webdata/web_data_service_unittest.cc8
221 files changed, 7785 insertions, 4608 deletions
diff --git a/chromium/components/autofill/core/browser/BUILD.gn b/chromium/components/autofill/core/browser/BUILD.gn
index fea04db6961..8b751bc708a 100644
--- a/chromium/components/autofill/core/browser/BUILD.gn
+++ b/chromium/components/autofill/core/browser/BUILD.gn
@@ -11,11 +11,14 @@ jumbo_static_library("browser") {
sources = [
"accessory_sheet_data.cc",
"accessory_sheet_data.h",
- "account_info_getter.h",
"address.cc",
"address.h",
"address_combobox_model.cc",
"address_combobox_model.h",
+ "address_contact_form_label_formatter.cc",
+ "address_contact_form_label_formatter.h",
+ "address_email_form_label_formatter.cc",
+ "address_email_form_label_formatter.h",
"address_field.cc",
"address_field.h",
"address_form_label_formatter.cc",
@@ -27,6 +30,8 @@ jumbo_static_library("browser") {
"address_normalizer.h",
"address_normalizer_impl.cc",
"address_normalizer_impl.h",
+ "address_phone_form_label_formatter.cc",
+ "address_phone_form_label_formatter.h",
"address_rewriter.cc",
"address_rewriter.h",
"address_rewriter_rules.cc",
@@ -88,12 +93,6 @@ jumbo_static_library("browser") {
"autofill_subject.h",
"autofill_type.cc",
"autofill_type.h",
- "autofill_wallet_data_type_controller.cc",
- "autofill_wallet_data_type_controller.h",
- "autofill_wallet_model_type_controller.cc",
- "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",
@@ -108,10 +107,6 @@ jumbo_static_library("browser") {
"credit_card.h",
"credit_card_field.cc",
"credit_card_field.h",
- "credit_card_save_manager.cc",
- "credit_card_save_manager.h",
- "credit_card_save_strike_database.cc",
- "credit_card_save_strike_database.h",
"email_field.cc",
"email_field.h",
"field_candidates.cc",
@@ -133,14 +128,6 @@ jumbo_static_library("browser") {
"label_formatter.h",
"label_formatter_utils.cc",
"label_formatter_utils.h",
- "legacy_strike_database.cc",
- "legacy_strike_database.h",
- "legal_message_line.cc",
- "legal_message_line.h",
- "local_card_migration_manager.cc",
- "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",
@@ -150,13 +137,27 @@ jumbo_static_library("browser") {
"metrics/form_events.h",
"name_field.cc",
"name_field.h",
- "password_requirements_spec_fetcher.h",
- "password_requirements_spec_fetcher_impl.cc",
- "password_requirements_spec_fetcher_impl.h",
- "password_requirements_spec_printer.cc",
- "password_requirements_spec_printer.h",
+ "payments/account_info_getter.h",
+ "payments/autofill_wallet_data_type_controller.cc",
+ "payments/autofill_wallet_data_type_controller.h",
+ "payments/autofill_wallet_model_type_controller.cc",
+ "payments/autofill_wallet_model_type_controller.h",
+ "payments/card_unmask_delegate.cc",
+ "payments/card_unmask_delegate.h",
+ "payments/credit_card_save_manager.cc",
+ "payments/credit_card_save_manager.h",
+ "payments/credit_card_save_strike_database.cc",
+ "payments/credit_card_save_strike_database.h",
"payments/full_card_request.cc",
"payments/full_card_request.h",
+ "payments/legacy_strike_database.cc",
+ "payments/legacy_strike_database.h",
+ "payments/legal_message_line.cc",
+ "payments/legal_message_line.h",
+ "payments/local_card_migration_manager.cc",
+ "payments/local_card_migration_manager.h",
+ "payments/local_card_migration_strike_database.cc",
+ "payments/local_card_migration_strike_database.h",
"payments/payments_client.cc",
"payments/payments_client.h",
"payments/payments_customer_data.h",
@@ -165,6 +166,13 @@ jumbo_static_library("browser") {
"payments/payments_service_url.h",
"payments/payments_util.cc",
"payments/payments_util.h",
+ "payments/risk_data_loader.h",
+ "payments/strike_database.cc",
+ "payments/strike_database.h",
+ "payments/strike_database_integrator_base.cc",
+ "payments/strike_database_integrator_base.h",
+ "payments/strike_database_integrator_test_strike_database.cc",
+ "payments/strike_database_integrator_test_strike_database.h",
"personal_data_manager.cc",
"personal_data_manager.h",
"personal_data_manager_observer.h",
@@ -187,17 +195,10 @@ jumbo_static_library("browser") {
"region_data_loader.h",
"region_data_loader_impl.cc",
"region_data_loader_impl.h",
- "risk_data_loader.h",
"search_field.cc",
"search_field.h",
"state_names.cc",
"state_names.h",
- "strike_database.cc",
- "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",
@@ -209,10 +210,10 @@ jumbo_static_library("browser") {
"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",
- "ui/card_unmask_prompt_view.h",
+ "ui/payments/card_unmask_prompt_controller.h",
+ "ui/payments/card_unmask_prompt_controller_impl.cc",
+ "ui/payments/card_unmask_prompt_controller_impl.h",
+ "ui/payments/card_unmask_prompt_view.h",
"validation.cc",
"validation.h",
"webdata/autocomplete_sync_bridge.cc",
@@ -246,10 +247,11 @@ jumbo_static_library("browser") {
"webdata/autofill_wallet_sync_bridge.h",
"webdata/autofill_wallet_syncable_service.cc",
"webdata/autofill_wallet_syncable_service.h",
- "webdata/autofill_webdata.h",
"webdata/autofill_webdata_backend.h",
"webdata/autofill_webdata_backend_impl.cc",
"webdata/autofill_webdata_backend_impl.h",
+ "webdata/autofill_webdata_backend_util.cc",
+ "webdata/autofill_webdata_backend_util.h",
"webdata/autofill_webdata_service.cc",
"webdata/autofill_webdata_service.h",
"webdata/autofill_webdata_service_observer.h",
@@ -268,23 +270,23 @@ jumbo_static_library("browser") {
sources += [
"autofill_assistant.cc",
"autofill_assistant.h",
- "autofill_credit_card_filling_infobar_delegate_mobile.cc",
- "autofill_credit_card_filling_infobar_delegate_mobile.h",
- "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",
+ "payments/autofill_credit_card_filling_infobar_delegate_mobile.cc",
+ "payments/autofill_credit_card_filling_infobar_delegate_mobile.h",
+ "payments/autofill_save_card_infobar_delegate_mobile.cc",
+ "payments/autofill_save_card_infobar_delegate_mobile.h",
+ "payments/autofill_save_card_infobar_mobile.h",
+ "ui/payments/card_expiration_date_fix_flow_view_delegate_mobile.cc",
+ "ui/payments/card_expiration_date_fix_flow_view_delegate_mobile.h",
+ "ui/payments/card_name_fix_flow_view_delegate_mobile.cc",
+ "ui/payments/card_name_fix_flow_view_delegate_mobile.h",
]
}
if (!is_android) {
sources += [
- "ui/local_card_migration_bubble_controller.h",
- "ui/local_card_migration_dialog_controller.h",
- "ui/save_card_bubble_controller.h",
+ "ui/payments/local_card_migration_bubble_controller.h",
+ "ui/payments/local_card_migration_dialog_controller.h",
+ "ui/payments/save_card_bubble_controller.h",
]
}
@@ -312,8 +314,6 @@ jumbo_static_library("browser") {
"//third_party/libaddressinput",
]
deps = [
- ":password_generator",
- ":password_generator_fips181",
"proto:legacy_proto_bridge",
"//base",
"//base:i18n",
@@ -378,8 +378,18 @@ jumbo_static_library("test_support") {
"data_driven_test.h",
"mock_autocomplete_history_manager.cc",
"mock_autocomplete_history_manager.h",
+ "payments/test_credit_card_save_manager.cc",
+ "payments/test_credit_card_save_manager.h",
+ "payments/test_credit_card_save_strike_database.cc",
+ "payments/test_credit_card_save_strike_database.h",
+ "payments/test_legacy_strike_database.cc",
+ "payments/test_legacy_strike_database.h",
+ "payments/test_local_card_migration_manager.cc",
+ "payments/test_local_card_migration_manager.h",
"payments/test_payments_client.cc",
"payments/test_payments_client.h",
+ "payments/test_strike_database.cc",
+ "payments/test_strike_database.h",
"suggestion_test_helpers.h",
"test_address_normalizer.cc",
"test_address_normalizer.h",
@@ -403,25 +413,15 @@ jumbo_static_library("test_support") {
"test_autofill_profile_validator_delayed.h",
"test_autofill_provider.cc",
"test_autofill_provider.h",
- "test_credit_card_save_manager.cc",
- "test_credit_card_save_manager.h",
- "test_credit_card_save_strike_database.cc",
- "test_credit_card_save_strike_database.h",
"test_event_waiter.h",
"test_form_data_importer.cc",
"test_form_data_importer.h",
"test_form_structure.cc",
"test_form_structure.h",
- "test_legacy_strike_database.cc",
- "test_legacy_strike_database.h",
- "test_local_card_migration_manager.cc",
- "test_local_card_migration_manager.h",
"test_personal_data_manager.cc",
"test_personal_data_manager.h",
"test_region_data_loader.cc",
"test_region_data_loader.h",
- "test_strike_database.cc",
- "test_strike_database.h",
"webdata/autofill_sync_bridge_test_util.cc",
"webdata/autofill_sync_bridge_test_util.h",
"webdata/mock_autofill_webdata_backend.cc",
@@ -459,30 +459,6 @@ jumbo_static_library("test_support") {
]
}
-static_library("password_generator") {
- sources = [
- "password_generator.cc",
- "password_generator.h",
- ]
- public_deps = [
- "//components/autofill/core/browser/proto",
- ]
- deps = [
- "//base",
- ]
-}
-
-static_library("password_generator_fips181") {
- sources = [
- "password_generator_fips181.cc",
- "password_generator_fips181.h",
- ]
- deps = [
- "//base",
- "//third_party/fips181",
- ]
-}
-
bundle_data("unit_tests_bundle_data") {
sources = [
"//components/test/data/autofill/merge/input/ambiguous.in",
@@ -535,30 +511,28 @@ source_set("unit_tests") {
"autofill_profile_validator_unittest.cc",
"autofill_subject_unittest.cc",
"autofill_type_unittest.cc",
- "autofill_wallet_data_type_controller_unittest.cc",
"contact_info_unittest.cc",
"country_combobox_model_unittest.cc",
"country_names_unittest.cc",
"credit_card_field_unittest.cc",
- "credit_card_save_manager_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",
"name_field_unittest.cc",
- "password_generator_fips181_unittest.cc",
- "password_generator_unittest.cc",
- "password_requirements_spec_fetcher_unittest.cc",
+ "payments/autofill_wallet_data_type_controller_unittest.cc",
+ "payments/credit_card_save_manager_unittest.cc",
"payments/full_card_request_unittest.cc",
+ "payments/legacy_strike_database_unittest.cc",
+ "payments/legal_message_line_unittest.cc",
+ "payments/local_card_migration_manager_unittest.cc",
"payments/payments_client_unittest.cc",
"payments/payments_service_url_unittest.cc",
"payments/payments_util_unittest.cc",
+ "payments/strike_database_integrator_test_strike_database_unittest.cc",
+ "payments/strike_database_unittest.cc",
"personal_data_manager_unittest.cc",
"phone_field_unittest.cc",
"phone_number_i18n_unittest.cc",
@@ -569,11 +543,9 @@ source_set("unit_tests") {
"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",
- "ui/card_unmask_prompt_controller_impl_unittest.cc",
+ "ui/payments/card_unmask_prompt_controller_impl_unittest.cc",
"validation_unittest.cc",
"webdata/autocomplete_sync_bridge_unittest.cc",
"webdata/autofill_profile_sync_bridge_unittest.cc",
@@ -600,12 +572,22 @@ source_set("unit_tests") {
]
}
+ if (!is_ios && !is_android) {
+ sources += [
+ "address_contact_form_label_formatter_unittest.cc",
+ "address_email_form_label_formatter_unittest.cc",
+ "address_form_label_formatter_unittest.cc",
+ "address_phone_form_label_formatter_unittest.cc",
+ "contact_form_label_formatter_unittest.cc",
+ "label_formatter_unittest.cc",
+ "label_formatter_utils_unittest.cc",
+ ]
+ }
+
defines = [ "CHROME_VERSION_MAJOR=" + chrome_version_major ]
deps = [
":browser",
- ":password_generator",
- ":password_generator_fips181",
":test_support",
":unit_tests_bundle_data",
"proto:legacy_proto_bridge",
@@ -665,15 +647,6 @@ fuzzer_test("form_structure_fuzzer") {
dict = "form_structure_fuzzer.dict"
}
-fuzzer_test("password_generator_fips181_fuzzer") {
- sources = [
- "password_generator_fips181_fuzzer.cc",
- ]
- deps = [
- ":password_generator_fips181",
- ]
-}
-
if (use_libfuzzer) {
fuzzer_test("form_structure_process_query_response_fuzzer") {
sources = [
@@ -688,17 +661,6 @@ if (use_libfuzzer) {
"//third_party/libprotobuf-mutator",
]
}
-
- fuzzer_test("password_generator_proto_fuzzer") {
- sources = [
- "password_generator_proto_fuzzer.cc",
- ]
- deps = [
- ":password_generator",
- "//components/autofill/core/browser/proto",
- "//third_party/libprotobuf-mutator",
- ]
- }
}
fuzzer_test("autofill_phone_number_i18n_fuzzer") {
diff --git a/chromium/components/autofill/core/browser/DEPS b/chromium/components/autofill/core/browser/DEPS
index 3536f9f5ce0..55b6c82a628 100644
--- a/chromium/components/autofill/core/browser/DEPS
+++ b/chromium/components/autofill/core/browser/DEPS
@@ -32,7 +32,6 @@ include_rules = [
"+services/network/public",
"+services/network/test",
"+sql",
- "+third_party/fips181",
"+third_party/libaddressinput", # For address i18n.
"+third_party/libphonenumber", # For phone number i18n.
"+third_party/re2",
diff --git a/chromium/components/autofill/core/browser/OWNERS b/chromium/components/autofill/core/browser/OWNERS
index 013fa313149..c23e8389686 100644
--- a/chromium/components/autofill/core/browser/OWNERS
+++ b/chromium/components/autofill/core/browser/OWNERS
@@ -1 +1,4 @@
parastoog@google.com
+
+per-file *type_controller*=jkrcal@chromium.org
+per-file *type_controller*=file://components/sync/OWNERS
diff --git a/chromium/components/autofill/core/browser/address_contact_form_label_formatter.cc b/chromium/components/autofill/core/browser/address_contact_form_label_formatter.cc
new file mode 100644
index 00000000000..32b1a9de7be
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_contact_form_label_formatter.cc
@@ -0,0 +1,61 @@
+// 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_contact_form_label_formatter.h"
+
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
+namespace autofill {
+
+AddressContactFormLabelFormatter::AddressContactFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types,
+ bool show_phone,
+ bool show_email)
+ : LabelFormatter(app_locale, focused_field_type, groups, field_types),
+ form_has_street_address_(HasStreetAddress(field_types_for_labels())),
+ show_phone_(show_phone),
+ show_email_(show_email) {}
+
+AddressContactFormLabelFormatter::~AddressContactFormLabelFormatter() {}
+
+// Note that the order in which parts of the label are added--name, street
+// address, phone, and email--ensures that the label is formatted correctly for
+// |focused_group|, |focused_field_type_|, and this kind of formatter.
+base::string16 AddressContactFormLabelFormatter::GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const {
+ std::vector<base::string16> label_parts;
+
+ bool street_address_is_focused = focused_group == ADDRESS_HOME &&
+ IsStreetAddressPart(focused_field_type());
+ bool non_street_address_is_focused =
+ focused_group == ADDRESS_HOME &&
+ !IsStreetAddressPart(focused_field_type());
+
+ if (focused_group != NAME && !non_street_address_is_focused) {
+ AddLabelPartIfNotEmpty(GetLabelName(profile, app_locale()), &label_parts);
+ }
+
+ if (!street_address_is_focused) {
+ AddLabelPartIfNotEmpty(
+ GetLabelAddress(form_has_street_address_, profile, app_locale(),
+ field_types_for_labels()),
+ &label_parts);
+ }
+
+ if (focused_group != PHONE_HOME && show_phone_) {
+ AddLabelPartIfNotEmpty(GetLabelPhone(profile, app_locale()), &label_parts);
+ }
+
+ if (focused_group != EMAIL && show_email_) {
+ AddLabelPartIfNotEmpty(GetLabelEmail(profile, app_locale()), &label_parts);
+ }
+
+ return ConstructLabelLine(label_parts);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_contact_form_label_formatter.h b/chromium/components/autofill/core/browser/address_contact_form_label_formatter.h
new file mode 100644
index 00000000000..eb851cab460
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_contact_form_label_formatter.h
@@ -0,0 +1,52 @@
+// 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_CONTACT_FORM_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_CONTACT_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, address, email, and phone fields.
+class AddressContactFormLabelFormatter : public LabelFormatter {
+ public:
+ AddressContactFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types,
+ bool show_phone,
+ bool show_email);
+
+ ~AddressContactFormLabelFormatter() override;
+
+ base::string16 GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const override;
+
+ private:
+ // True if this formatter's associated form has a street address field. A
+ // form may have an address-related field, e.g. zip code, without having a
+ // street address field. If a form does not include a street address field,
+ // street addresses should not appear in labels.
+ bool form_has_street_address_;
+
+ // True if phone numbers should be included in labels.
+ bool show_phone_;
+
+ // True if email addresses should be included in labels.
+ bool show_email_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_CONTACT_FORM_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc b/chromium/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc
new file mode 100644
index 00000000000..b9508f2c02e
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_contact_form_label_formatter_unittest.cc
@@ -0,0 +1,510 @@
+// 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_contact_form_label_formatter.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/guid.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+
+namespace autofill {
+namespace {
+
+std::vector<ServerFieldType> GetFieldTypes() {
+ return {NO_SERVER_DATA,
+ NAME_BILLING_FULL,
+ EMAIL_ADDRESS,
+ ADDRESS_BILLING_LINE1,
+ ADDRESS_BILLING_LINE2,
+ ADDRESS_BILLING_DEPENDENT_LOCALITY,
+ ADDRESS_BILLING_CITY,
+ ADDRESS_BILLING_STATE,
+ ADDRESS_BILLING_ZIP,
+ ADDRESS_BILLING_COUNTRY,
+ PHONE_BILLING_WHOLE_NUMBER};
+}
+
+TEST(AddressContactFormLabelFormatterTest, GetLabelsWithMissingProfiles) {
+ const std::vector<AutofillProfile*> profiles{};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles);
+ EXPECT_TRUE(formatter->GetLabels(profiles).empty());
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Sarah", "", "Revere", "sarah.revere@aol.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "16175232338");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "L", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "6175141600");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "Deborah", "", "Katabi", "deborah@mit.edu",
+ "", "", "", "", "", "", "US", "6173240000");
+
+ AutofillProfile profile5 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile5, "", "", "", "", "", "Old North Church",
+ "193 Salem St", "Boston", "MA", "02113", "US", "");
+
+ AutofillProfile profile6 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile6, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4, &profile5, &profile6};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("19 North Sq"),
+ base::ASCIIToUTF16("(617) 523-2338"),
+ base::ASCIIToUTF16("sarah.revere@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("(617) 514-1600")}),
+ ConstructLabelLine({base::ASCIIToUTF16("19 North Sq"),
+ base::ASCIIToUTF16("paul1775@gmail.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("(617) 324-0000"),
+ base::ASCIIToUTF16("deborah@mit.edu")}),
+ base::ASCIIToUTF16("Old North Church, 193 Salem St"),
+ base::string16()));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Sarah", "", "Revere", "sarah.revere@aol.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "16175232338");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "L", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "6175141600");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "Deborah", "", "Katabi", "deborah@mit.edu",
+ "", "", "", "", "", "", "US", "6173240000");
+
+ AutofillProfile profile5 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile5, "", "", "", "", "", "Old North Church",
+ "193 Salem St", "Boston", "MA", "02113", "US", "");
+
+ AutofillProfile profile6 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile6, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4, &profile5, &profile6};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("Sarah Revere"),
+ base::ASCIIToUTF16("(617) 523-2338"),
+ base::ASCIIToUTF16("sarah.revere@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Jackie L Kennedy"),
+ base::ASCIIToUTF16("(617) 514-1600")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Paul Revere"),
+ base::ASCIIToUTF16("paul1775@gmail.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Deborah Katabi"),
+ base::ASCIIToUTF16("(617) 324-0000"),
+ base::ASCIIToUTF16("deborah@mit.edu")}),
+ base::ASCIIToUTF16(""), base::string16()));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Sarah", "", "Revere", "sarah.revere@aol.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "16175232338");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "L", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "6175141600");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "Deborah", "", "Katabi", "deborah@mit.edu",
+ "", "", "", "", "", "", "US", "6173240000");
+
+ AutofillProfile profile5 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile5, "", "", "", "", "", "Old North Church",
+ "193 Salem St", "Boston", "MA", "02113", "US", "");
+
+ AutofillProfile profile6 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile6, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4, &profile5, &profile6};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_BILLING_CITY, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("19 North Sq"),
+ base::ASCIIToUTF16("(617) 523-2338"),
+ base::ASCIIToUTF16("sarah.revere@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("(617) 514-1600")}),
+ ConstructLabelLine({base::ASCIIToUTF16("19 North Sq"),
+ base::ASCIIToUTF16("paul1775@gmail.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("(617) 324-0000"),
+ base::ASCIIToUTF16("deborah@mit.edu")}),
+ base::ASCIIToUTF16("Old North Church, 193 Salem St"),
+ base::string16()));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedEmail) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Sarah", "", "Revere", "sarah.revere@aol.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "16175232338");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "L", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "6175141600");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "Deborah", "", "Katabi", "deborah@mit.edu",
+ "", "", "", "", "", "", "US", "6173240000");
+
+ AutofillProfile profile5 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile5, "", "", "", "", "", "Old North Church",
+ "193 Salem St", "Boston", "MA", "02113", "US", "");
+
+ AutofillProfile profile6 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile6, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4, &profile5, &profile6};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", EMAIL_ADDRESS, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("Sarah Revere"),
+ base::ASCIIToUTF16("19 North Sq"),
+ base::ASCIIToUTF16("(617) 523-2338")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Jackie L Kennedy"),
+ base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("(617) 514-1600")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Paul Revere"),
+ base::ASCIIToUTF16("19 North Sq")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Deborah Katabi"),
+ base::ASCIIToUTF16("(617) 324-0000")}),
+ base::ASCIIToUTF16("Old North Church, 193 Salem St"),
+ base::string16()));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedPhone) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Sarah", "", "Revere", "sarah.revere@aol.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "16175232338");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "L", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "6175141600");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "Deborah", "", "Katabi", "deborah@mit.edu",
+ "", "", "", "", "", "", "US", "6173240000");
+
+ AutofillProfile profile5 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile5, "", "", "", "", "", "Old North Church",
+ "193 Salem St", "Boston", "MA", "02113", "US", "");
+
+ AutofillProfile profile6 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile6, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4, &profile5, &profile6};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", PHONE_BILLING_WHOLE_NUMBER, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("Sarah Revere"),
+ base::ASCIIToUTF16("19 North Sq"),
+ base::ASCIIToUTF16("sarah.revere@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Jackie L Kennedy"),
+ base::ASCIIToUTF16("151 Irving Ave")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Paul Revere"),
+ base::ASCIIToUTF16("19 North Sq"),
+ base::ASCIIToUTF16("paul1775@gmail.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Deborah Katabi"),
+ base::ASCIIToUTF16("deborah@mit.edu")}),
+ base::ASCIIToUTF16("Old North Church, 193 Salem St"),
+ base::string16()));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", " SP ", " 04094-050 ", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", NAME_BILLING_FULL, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine(
+ {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"),
+ base::ASCIIToUTF16("(11) 2648-0254"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::UTF8ToUTF16("Estr. Dona Castorina, 110"),
+ base::ASCIIToUTF16("(21) 98765-0000"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", " SP ", " 04094-050 ", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::ASCIIToUTF16("(11) 2648-0254"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"),
+ base::ASCIIToUTF16("(21) 98765-0000"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", " SP ", " 04094-050 ", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_BILLING_ZIP, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine(
+ {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"),
+ base::ASCIIToUTF16("(11) 2648-0254"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Estr. Dona Castorina, 110"),
+ base::ASCIIToUTF16("(21) 98765-0000"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedEmail) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", " SP ", " 04094-050 ", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("pt-BR", EMAIL_ADDRESS, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine(
+ {base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"),
+ base::ASCIIToUTF16("(11) 2648-0254")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"),
+ base::UTF8ToUTF16("Estr. Dona Castorina, 110"),
+ base::ASCIIToUTF16("(21) 98765-0000")})));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedPhone) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", " SP ", " 04094-050 ", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", PHONE_BILLING_WHOLE_NUMBER, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine(
+ {base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"),
+ base::UTF8ToUTF16("Estr. Dona Castorina, 110"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(AddressContactFormLabelFormatterTest,
+ GetLabelsForFormWithPartialAddressFields) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Sarah", "", "Revere", "sarah.revere@aol.com",
+ "", "19 North Sq", "", "Boston", "MA", "02113", "US",
+ "16175232338");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", EMAIL_ADDRESS,
+ {NAME_BILLING_FULL, EMAIL_ADDRESS,
+ ADDRESS_BILLING_ZIP, PHONE_BILLING_WHOLE_NUMBER},
+ profiles);
+
+ // Checks that only address fields in the form are shown in the label.
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine(
+ {base::ASCIIToUTF16("Sarah Revere"), base::ASCIIToUTF16("02113")})));
+}
+
+} // namespace
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_email_form_label_formatter.cc b/chromium/components/autofill/core/browser/address_email_form_label_formatter.cc
new file mode 100644
index 00000000000..675bf30ade1
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_email_form_label_formatter.cc
@@ -0,0 +1,61 @@
+// 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_email_form_label_formatter.h"
+
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
+namespace autofill {
+
+AddressEmailFormLabelFormatter::AddressEmailFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types)
+ : LabelFormatter(app_locale, focused_field_type, groups, field_types),
+ form_has_street_address_(HasStreetAddress(field_types_for_labels())) {}
+
+AddressEmailFormLabelFormatter::~AddressEmailFormLabelFormatter() {}
+
+base::string16 AddressEmailFormLabelFormatter::GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const {
+ return focused_group == ADDRESS_HOME &&
+ !IsStreetAddressPart(focused_field_type())
+ ? GetLabelForProfileOnFocusedNonStreetAddress(
+ form_has_street_address_, profile, app_locale(),
+ field_types_for_labels(),
+ GetLabelEmail(profile, app_locale()))
+ : GetLabelForProfileOnFocusedNameEmailOrStreetAddress(
+ profile, focused_group);
+}
+
+// Note that the order--name, address, and email--in which parts of the label
+// are added ensures that the label is formatted correctly for |focused_group|,
+// |focused_field_type_| and for this kind of formatter.
+base::string16 AddressEmailFormLabelFormatter::
+ GetLabelForProfileOnFocusedNameEmailOrStreetAddress(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const {
+ std::vector<base::string16> label_parts;
+
+ if (focused_group != NAME) {
+ AddLabelPartIfNotEmpty(GetLabelName(profile, app_locale()), &label_parts);
+ }
+
+ if (focused_group != ADDRESS_HOME) {
+ AddLabelPartIfNotEmpty(
+ GetLabelAddress(form_has_street_address_, profile, app_locale(),
+ field_types_for_labels()),
+ &label_parts);
+ }
+
+ if (focused_group != EMAIL) {
+ AddLabelPartIfNotEmpty(GetLabelEmail(profile, app_locale()), &label_parts);
+ }
+
+ return ConstructLabelLine(label_parts);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_email_form_label_formatter.h b/chromium/components/autofill/core/browser/address_email_form_label_formatter.h
new file mode 100644
index 00000000000..5c44dba5cdf
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_email_form_label_formatter.h
@@ -0,0 +1,52 @@
+// 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_EMAIL_FORM_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_EMAIL_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, address, and email fields and without phone fields.
+class AddressEmailFormLabelFormatter : public LabelFormatter {
+ public:
+ AddressEmailFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types);
+
+ ~AddressEmailFormLabelFormatter() override;
+
+ base::string16 GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const override;
+
+ private:
+ // Returns a label to show the user when |focused_field_type_| is a type
+ // other than a non-street-address field type. For example,
+ // |focused_field_type_| could be last name, home street address, or email
+ // address.
+ base::string16 GetLabelForProfileOnFocusedNameEmailOrStreetAddress(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const;
+
+ // True if this formatter's associated form has a street address field. A
+ // form may have an address-related field, e.g. zip code, without having a
+ // street address field. If a form does not include a street address field,
+ // street addresses should not appear in labels.
+ bool form_has_street_address_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_EMAIL_FORM_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc b/chromium/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc
new file mode 100644
index 00000000000..34e2a2bab92
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_email_form_label_formatter_unittest.cc
@@ -0,0 +1,332 @@
+// 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_email_form_label_formatter.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/guid.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+
+namespace autofill {
+namespace {
+
+std::vector<ServerFieldType> GetFieldTypes() {
+ return {NAME_FULL,
+ EMAIL_ADDRESS,
+ ADDRESS_BILLING_LINE1,
+ ADDRESS_BILLING_LINE2,
+ ADDRESS_BILLING_CITY,
+ ADDRESS_BILLING_STATE,
+ ADDRESS_BILLING_DEPENDENT_LOCALITY,
+ ADDRESS_BILLING_ZIP,
+ ADDRESS_BILLING_COUNTRY};
+}
+
+TEST(AddressEmailFormLabelFormatterTest, GetLabelsWithMissingProfiles) {
+ const std::vector<AutofillProfile*> profiles{};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles);
+ EXPECT_TRUE(formatter->GetLabels(profiles).empty());
+}
+
+TEST(AddressEmailFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "", "", "", "", "", "US", "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "John", "", "Adams", "", "", "", "", "Quincy",
+ "MA", "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_BILLING_FULL, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("333 Washington St"),
+ base::ASCIIToUTF16("jfk@gmail.com")}),
+ base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("paul1775@gmail.com"), base::string16()));
+}
+
+TEST(AddressEmailFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "", "", "", "paul1775@gmail.com", "", "", "",
+ "", "", "", "US", "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "141 Franklin St", "",
+ "Quincy", "MA", "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("jfk@gmail.com")}),
+ base::ASCIIToUTF16("Jackie Kennedy"),
+ base::ASCIIToUTF16("paul1775@gmail.com"), base::string16()));
+}
+
+TEST(AddressEmailFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "", "", "", "paul1775@gmail.com", "", "", "",
+ "", "", "", "US", "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "", "", "Quincy", "MA",
+ "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_BILLING_ZIP, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("333 Washington St"),
+ base::ASCIIToUTF16("jfk@gmail.com")}),
+ base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("paul1775@gmail.com"), base::string16()));
+}
+
+TEST(AddressEmailFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedEmail) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "jackie@outlook.com",
+ "", "", "", "Hyannis", "MA", "02601", "US", "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "", "", "", "paul1775@gmail.com", "", "", "",
+ "", "", "", "US", "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "141 Franklin St", "",
+ "Quincy", "MA", "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", EMAIL_ADDRESS, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("333 Washington St")}),
+ base::ASCIIToUTF16("Jackie Kennedy"), base::string16(),
+ base::ASCIIToUTF16("141 Franklin St")));
+}
+
+TEST(AddressEmailFormLabelFormatterTest, GetLabelsForBRProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", NAME_BILLING_FULL, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine(
+ {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Estr. Dona Castorina, 110"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(AddressEmailFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_BILLING_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(AddressEmailFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_BILLING_DEPENDENT_LOCALITY, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine(
+ {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Estr. Dona Castorina, 110"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(AddressEmailFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedEmail) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("pt-BR", EMAIL_ADDRESS, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine(
+ {base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")}),
+ ConstructLabelLine(
+ {base::ASCIIToUTF16("Artur Avila"),
+ base::ASCIIToUTF16("Estr. Dona Castorina, 110")})));
+}
+
+TEST(AddressEmailFormLabelFormatterTest,
+ GetLabelsForFormWithAddressFieldsMinusStreetAddress) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", EMAIL_ADDRESS,
+ {NAME_BILLING_FULL, EMAIL_ADDRESS,
+ ADDRESS_BILLING_CITY, ADDRESS_BILLING_STATE},
+ profiles);
+
+ // Checks that only address fields in the form are shown in the label.
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("Brookline, MA")})));
+}
+
+} // namespace
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_form_label_formatter.cc b/chromium/components/autofill/core/browser/address_form_label_formatter.cc
index 604dd7882da..ec88eda9bf5 100644
--- a/chromium/components/autofill/core/browser/address_form_label_formatter.cc
+++ b/chromium/components/autofill/core/browser/address_form_label_formatter.cc
@@ -4,28 +4,35 @@
#include "components/autofill/core/browser/address_form_label_formatter.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
namespace autofill {
AddressFormLabelFormatter::AddressFormLabelFormatter(
const std::string& app_locale,
ServerFieldType focused_field_type,
+ uint32_t groups,
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);
- }
- }
-}
+ : LabelFormatter(app_locale, focused_field_type, groups, field_types),
+ form_has_street_address_(HasStreetAddress(field_types_for_labels())) {}
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;
+base::string16 AddressFormLabelFormatter::GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const {
+ if (focused_group != ADDRESS_HOME) {
+ return GetLabelNationalAddress(profile, app_locale(),
+ field_types_for_labels());
+ } else {
+ std::vector<base::string16> label_parts;
+ AddLabelPartIfNotEmpty(GetLabelName(profile, app_locale()), &label_parts);
+ AddLabelPartIfNotEmpty(GetLabelForFocusedAddress(
+ focused_field_type(), form_has_street_address_,
+ profile, app_locale(), field_types_for_labels()),
+ &label_parts);
+ return ConstructLabelLine(label_parts);
+ }
}
} // 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
index 1f0c4850a3d..e4a97dcd759 100644
--- a/chromium/components/autofill/core/browser/address_form_label_formatter.h
+++ b/chromium/components/autofill/core/browser/address_form_label_formatter.h
@@ -21,17 +21,21 @@ class AddressFormLabelFormatter : public LabelFormatter {
public:
AddressFormLabelFormatter(const std::string& app_locale,
ServerFieldType focused_field_type,
+ uint32_t groups,
const std::vector<ServerFieldType>& field_types);
~AddressFormLabelFormatter() override;
- std::vector<base::string16> GetLabels(
- const std::vector<AutofillProfile*>& profiles) const override;
+ base::string16 GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) 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_;
+ // True if this formatter's associated form has a street address field. A
+ // form may have an address-related field, e.g. zip code, without having a
+ // street address field. If a form does not include a street address field,
+ // street addresses should not appear in labels.
+ bool form_has_street_address_;
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_form_label_formatter_unittest.cc b/chromium/components/autofill/core/browser/address_form_label_formatter_unittest.cc
new file mode 100644
index 00000000000..4f7a554bf19
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_form_label_formatter_unittest.cc
@@ -0,0 +1,191 @@
+// 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"
+
+#include <vector>
+
+#include "base/guid.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+
+namespace autofill {
+namespace {
+
+std::vector<ServerFieldType> GetFieldTypes() {
+ return {NO_SERVER_DATA, NAME_FIRST,
+ NAME_LAST, ADDRESS_HOME_LINE1,
+ ADDRESS_HOME_LINE2, ADDRESS_HOME_DEPENDENT_LOCALITY,
+ ADDRESS_HOME_CITY, ADDRESS_HOME_STATE,
+ ADDRESS_HOME_ZIP, ADDRESS_HOME_COUNTRY};
+}
+
+TEST(AddressFormLabelFormatterTest, GetLabelsWithMissingProfiles) {
+ const std::vector<AutofillProfile*> profiles{};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", NAME_FIRST, GetFieldTypes(), profiles);
+ EXPECT_TRUE(formatter->GetLabels(profiles).empty());
+}
+
+TEST(AddressFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "", "", "", "jackie@outlook.com", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "", "US",
+ "5087717796");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "", "", "", "", "", "US", "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine(
+ {base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("Brookline, MA 02445")}),
+ base::ASCIIToUTF16("Hyannis, MA"),
+ base::ASCIIToUTF16("Paul Revere"), base::string16()));
+}
+
+TEST(AddressFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "", "", "", "jackie@outlook.com", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "", "US",
+ "5087717796");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "paul1775@gmail.com",
+ "", "", "", "", "", "", "US", "");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_HOME_CITY, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("333 Washington St")}),
+ base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("Paul Revere"), base::string16()));
+}
+
+TEST(AddressFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "jackie@outlook.com",
+ "", "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "5087717796");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", NAME_FIRST, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(base::ASCIIToUTF16("333 Washington St, Brookline, MA 02445"),
+ base::ASCIIToUTF16("151 Irving Ave, Hyannis, MA 02601")));
+}
+
+TEST(AddressFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine(
+ {base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::UTF8ToUTF16("Vila Mariana, São Paulo-SP, 04094-050")})));
+}
+
+TEST(AddressFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_HOME_ZIP, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine(
+ {base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")})));
+}
+
+TEST(AddressFormLabelFormatterTest, GetLabelsForBRProfilesAndFocusedName) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("pt-BR", NAME_FIRST, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(formatter->GetLabels(profiles),
+ ElementsAre(base::UTF8ToUTF16(
+ "Av. Pedro Álvares Cabral, 1301, Vila Mariana, São "
+ "Paulo-SP, 04094-050")));
+}
+
+} // namespace
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_phone_form_label_formatter.cc b/chromium/components/autofill/core/browser/address_phone_form_label_formatter.cc
new file mode 100644
index 00000000000..97e374b27d9
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_phone_form_label_formatter.cc
@@ -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.
+
+#include "components/autofill/core/browser/address_phone_form_label_formatter.h"
+
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
+namespace autofill {
+
+AddressPhoneFormLabelFormatter::AddressPhoneFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types)
+ : LabelFormatter(app_locale, focused_field_type, groups, field_types),
+ form_has_street_address_(HasStreetAddress(field_types_for_labels())) {}
+
+AddressPhoneFormLabelFormatter::~AddressPhoneFormLabelFormatter() {}
+
+base::string16 AddressPhoneFormLabelFormatter::GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const {
+ return focused_group == ADDRESS_HOME &&
+ !IsStreetAddressPart(focused_field_type())
+ ? GetLabelForProfileOnFocusedNonStreetAddress(
+ form_has_street_address_, profile, app_locale(),
+ field_types_for_labels(),
+ GetLabelPhone(profile, app_locale()))
+ : GetLabelForProfileOnFocusedNamePhoneOrStreetAddress(
+ profile, focused_group);
+}
+
+// Note that the order--name, phone, and address--in which parts of the label
+// are added ensures that the label is formatted correctly for |focused_group|,
+// |focused_field_type_| and for this kind of formatter.
+base::string16 AddressPhoneFormLabelFormatter::
+ GetLabelForProfileOnFocusedNamePhoneOrStreetAddress(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const {
+ std::vector<base::string16> label_parts;
+ if (focused_group != NAME) {
+ AddLabelPartIfNotEmpty(GetLabelName(profile, app_locale()), &label_parts);
+ }
+
+ if (focused_group != PHONE_HOME) {
+ AddLabelPartIfNotEmpty(GetLabelPhone(profile, app_locale()), &label_parts);
+ }
+
+ if (focused_group != ADDRESS_HOME) {
+ AddLabelPartIfNotEmpty(
+ GetLabelAddress(form_has_street_address_, profile, app_locale(),
+ field_types_for_labels()),
+ &label_parts);
+ }
+
+ return ConstructLabelLine(label_parts);
+}
+
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/address_phone_form_label_formatter.h b/chromium/components/autofill/core/browser/address_phone_form_label_formatter.h
new file mode 100644
index 00000000000..231ca9e5084
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_phone_form_label_formatter.h
@@ -0,0 +1,51 @@
+// 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_PHONE_FORM_LABEL_FORMATTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_PHONE_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, address, and phone fields and without email fields.
+class AddressPhoneFormLabelFormatter : public LabelFormatter {
+ public:
+ AddressPhoneFormLabelFormatter(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types);
+
+ ~AddressPhoneFormLabelFormatter() override;
+
+ base::string16 GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const override;
+
+ private:
+ // Returns a label to show the user when |focused_field_type_| is a type
+ // other than a non-street-address field type. For example,
+ // |focused_field_type_| could be first name, address line 1, or phone number.
+ base::string16 GetLabelForProfileOnFocusedNamePhoneOrStreetAddress(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const;
+
+ // True if this formatter's associated form has a street address field. A
+ // form may have an address-related field, e.g. zip code, without having a
+ // street address field. If a form does not include a street address field,
+ // street addresses should not appear in labels.
+ bool form_has_street_address_;
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_PHONE_FORM_LABEL_FORMATTER_H_
diff --git a/chromium/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc b/chromium/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc
new file mode 100644
index 00000000000..caf0e181a09
--- /dev/null
+++ b/chromium/components/autofill/core/browser/address_phone_form_label_formatter_unittest.cc
@@ -0,0 +1,325 @@
+// 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_phone_form_label_formatter.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/guid.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+
+namespace autofill {
+namespace {
+
+std::vector<ServerFieldType> GetFieldTypes() {
+ return {NO_SERVER_DATA, NAME_FULL, PHONE_HOME_WHOLE_NUMBER,
+ ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2, ADDRESS_HOME_CITY,
+ ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP, ADDRESS_HOME_COUNTRY};
+}
+
+TEST(AddressPhoneFormLabelFormatterTest, GetLabelsWithMissingProfiles) {
+ const std::vector<AutofillProfile*> profiles{};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", NAME_FULL, GetFieldTypes(), profiles);
+ EXPECT_TRUE(formatter->GetLabels(profiles).empty());
+}
+
+TEST(AddressPhoneFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "", "", "", "", "", "",
+ "", "US", "6175232338");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "John", "", "Adams", "", "", "", "", "", "",
+ "", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", NAME_FULL, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("(617) 730-2000"),
+ base::ASCIIToUTF16("333 Washington St")}),
+ base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("(617) 523-2338"), base::string16()));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "", "", "", "", "", "", "", "", "", "", "US",
+ "6175232338");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "141 Franklin St", "",
+ "Quincy", "MA", "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("(617) 730-2000")}),
+ base::ASCIIToUTF16("Jackie Kennedy"),
+ base::ASCIIToUTF16("(617) 523-2338"), base::string16()));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "", "",
+ "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "", "", "", "", "", "", "", "", "", "", "US",
+ "6175232338");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "", "", "Quincy", "MA",
+ "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", ADDRESS_HOME_CITY, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("333 Washington St"),
+ base::ASCIIToUTF16("(617) 730-2000")}),
+ base::ASCIIToUTF16("151 Irving Ave"),
+ base::ASCIIToUTF16("(617) 523-2338"), base::string16()));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest,
+ GetLabelsForUSProfilesAndFocusedPhone) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "", "", "", "", "",
+ "", "", "US", "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "", "", "", "", "", "Paul Revere House",
+ "19 North Square", "Boston", "MA", "02113", "US",
+ "6175232338");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "", "", "", "", "", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", PHONE_HOME_WHOLE_NUMBER, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("333 Washington St")}),
+ base::ASCIIToUTF16("Jackie Kennedy"),
+ base::ASCIIToUTF16("Paul Revere House, 19 North Square"),
+ base::string16()));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest, GetLabelsForBRProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("pt-BR", NAME_FULL, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine(
+ {base::ASCIIToUTF16("(11) 2648-0254"),
+ base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")}),
+ ConstructLabelLine(
+ {base::ASCIIToUTF16("(21) 98765-0000"),
+ base::ASCIIToUTF16("Estr. Dona Castorina, 110")})));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_HOME_LINE1, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::ASCIIToUTF16("(11) 2648-0254")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"),
+ base::ASCIIToUTF16("(21) 98765-0000")})));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedNonStreetAddress) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", ADDRESS_HOME_ZIP, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine(
+ {base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301"),
+ base::ASCIIToUTF16("(11) 2648-0254")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Estr. Dona Castorina, 110"),
+ base::ASCIIToUTF16("(21) 98765-0000")})));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest,
+ GetLabelsForBRProfilesAndFocusedPhone) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", PHONE_HOME_WHOLE_NUMBER, GetFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine(
+ {base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::UTF8ToUTF16("Av. Pedro Álvares Cabral, 1301")}),
+ ConstructLabelLine(
+ {base::ASCIIToUTF16("Artur Avila"),
+ base::ASCIIToUTF16("Estr. Dona Castorina, 110")})));
+}
+
+TEST(AddressPhoneFormLabelFormatterTest,
+ GetLabelsForFormWithAddressFieldsMinusStreetAddress) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", PHONE_HOME_WHOLE_NUMBER,
+ {NAME_FULL, PHONE_HOME_WHOLE_NUMBER, ADDRESS_HOME_ZIP}, profiles);
+
+ // Checks that only address fields in the form are shown in the label.
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("02445")})));
+}
+
+} // namespace
+} // namespace autofill \ No newline at end of file
diff --git a/chromium/components/autofill/core/browser/autocomplete_history_manager.cc b/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
index 8eae19020de..f484db2d6cb 100644
--- a/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
+++ b/chromium/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -122,6 +122,11 @@ void AutocompleteHistoryManager::Init(
pref_service_ = pref_service;
is_off_the_record_ = is_off_the_record;
+ if (!profile_database_) {
+ // In some tests, there are no dbs.
+ return;
+ }
+
// No need to run the retention policy in OTR.
if (!is_off_the_record_ &&
base::FeatureList::IsEnabled(
diff --git a/chromium/components/autofill/core/browser/autocomplete_history_manager_unittest.cc b/chromium/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
index 249abd01d70..4c662e11e9f 100644
--- a/chromium/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
@@ -164,7 +164,7 @@ class AutocompleteHistoryManagerTest : public testing::Test {
TEST_F(AutocompleteHistoryManagerTest, CreditCardNumberValue) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Valid Visa credit card number pulled from the paypal help site.
@@ -186,7 +186,7 @@ TEST_F(AutocompleteHistoryManagerTest, CreditCardNumberValue) {
TEST_F(AutocompleteHistoryManagerTest, NonCreditCardNumberValue) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Invalid credit card number.
@@ -206,7 +206,7 @@ TEST_F(AutocompleteHistoryManagerTest, NonCreditCardNumberValue) {
TEST_F(AutocompleteHistoryManagerTest, SSNValue) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData ssn;
@@ -225,7 +225,7 @@ TEST_F(AutocompleteHistoryManagerTest, SSNValue) {
TEST_F(AutocompleteHistoryManagerTest, SearchField) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Search field.
@@ -244,7 +244,7 @@ TEST_F(AutocompleteHistoryManagerTest, SearchField) {
TEST_F(AutocompleteHistoryManagerTest, AutocompleteFeatureOff) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Search field.
@@ -267,7 +267,7 @@ TEST_F(AutocompleteHistoryManagerTest, AutocompleteFeatureOff) {
TEST_F(AutocompleteHistoryManagerTest, FieldWithAutocompleteOff) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Field specifying autocomplete="off".
@@ -290,7 +290,7 @@ TEST_F(AutocompleteHistoryManagerTest, Incognito) {
/*is_off_the_record_=*/true);
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Search field.
@@ -311,7 +311,7 @@ TEST_F(AutocompleteHistoryManagerTest, Incognito) {
TEST_F(AutocompleteHistoryManagerTest, NonFocusableField) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Unfocusable field.
@@ -333,7 +333,7 @@ TEST_F(AutocompleteHistoryManagerTest, NonFocusableField) {
TEST_F(AutocompleteHistoryManagerTest, PresentationField) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Presentation field.
@@ -400,6 +400,21 @@ TEST_F(AutocompleteHistoryManagerTest,
/*is_off_the_record=*/false);
}
+// Tests that the Init function will not crash even if we don't have a DB.
+TEST_F(AutocompleteHistoryManagerTest, Init_NullDB_NoCrash) {
+ // Enable the feature, and set the major version.
+ scoped_features.InitAndEnableFeature(
+ features::kAutocompleteRetentionPolicyEnabled);
+ prefs_->SetInteger(prefs::kAutocompleteLastVersionRetentionPolicy,
+ CHROME_VERSION_MAJOR - 1);
+
+ EXPECT_CALL(*web_data_service_,
+ RemoveExpiredAutocompleteEntries(autocomplete_manager_.get()))
+ .Times(0);
+ autocomplete_manager_->Init(nullptr, prefs_.get(),
+ /*is_off_the_record=*/false);
+}
+
// Tests that the Init function will not trigger the Autocomplete Retention
// Policy when running in a major version that was already cleaned.
TEST_F(AutocompleteHistoryManagerTest,
@@ -872,7 +887,7 @@ TEST_F(AutocompleteHistoryManagerTest,
TEST_F(AutocompleteHistoryManagerTest, NoAutocompleteSuggestionsForTextarea) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
diff --git a/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc b/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc
index 958759bc688..365e2f8ea55 100644
--- a/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_assistant_unittest.cc
@@ -18,9 +18,9 @@
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
+#include "components/autofill/core/browser/payments/test_credit_card_save_manager.h"
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
-#include "components/autofill/core/browser/test_credit_card_save_manager.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
@@ -70,9 +70,9 @@ class AutofillAssistantTest : public testing::Test {
void SetUp() {
payments::TestPaymentsClient* payments_client =
- new payments::TestPaymentsClient(
- autofill_driver_.GetURLLoaderFactory(), autofill_client_.GetPrefs(),
- autofill_client_.GetIdentityManager(), &pdm_);
+ new payments::TestPaymentsClient(autofill_driver_.GetURLLoaderFactory(),
+ autofill_client_.GetIdentityManager(),
+ &pdm_);
autofill_client_.set_test_payments_client(
std::unique_ptr<payments::TestPaymentsClient>(payments_client));
TestCreditCardSaveManager* credit_card_save_manager =
@@ -101,7 +101,7 @@ class AutofillAssistantTest : public testing::Test {
// Returns a valid credit card form.
FormData CreateValidCreditCardFormData() {
FormData form;
- form.origin = GURL("https://myform.com");
+ form.url = GURL("https://myform.com");
form.action = GURL("https://myform.com/submit");
FormFieldData field;
@@ -202,7 +202,7 @@ TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn_NotSecure) {
// Cannot be shown if the context is not secure.
FormData form = CreateValidCreditCardFormData();
- form.origin = GURL("http://myform.com");
+ form.url = GURL("http://myform.com");
form.action = GURL("http://myform.com/submit");
auto form_structure = std::make_unique<FormStructure>(form);
form_structure->DetermineHeuristicTypes();
diff --git a/chromium/components/autofill/core/browser/autofill_client.h b/chromium/components/autofill/core/browser/autofill_client.h
index 0341ce2c565..a60e5f6b0d9 100644
--- a/chromium/components/autofill/core/browser/autofill_client.h
+++ b/chromium/components/autofill/core/browser/autofill_client.h
@@ -15,7 +15,7 @@
#include "base/strings/string16.h"
#include "base/values.h"
#include "build/build_config.h"
-#include "components/autofill/core/browser/risk_data_loader.h"
+#include "components/autofill/core/browser/payments/risk_data_loader.h"
#include "components/security_state/core/security_state.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "ui/base/window_open_disposition.h"
@@ -125,6 +125,11 @@ class AutofillClient : public RiskDataLoader {
// Used for options of upload prompt.
struct SaveCreditCardOptions {
+ SaveCreditCardOptions& with_from_dynamic_change_form(bool b) {
+ from_dynamic_change_form = b;
+ return *this;
+ }
+
SaveCreditCardOptions& with_has_non_focusable_field(bool b) {
has_non_focusable_field = b;
return *this;
@@ -146,6 +151,7 @@ class AutofillClient : public RiskDataLoader {
return *this;
}
+ bool from_dynamic_change_form = false;
bool has_non_focusable_field = false;
bool should_request_name_from_user = false;
bool should_request_expiration_date_from_user = false;
diff --git a/chromium/components/autofill/core/browser/autofill_data_model.cc b/chromium/components/autofill/core/browser/autofill_data_model.cc
index 59f83e57b3e..7858c3dfd5b 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_model.cc
@@ -44,7 +44,8 @@ bool AutofillDataModel::HasGreaterFrecencyThan(
double other_score = other->GetFrecencyScore(comparison_time);
// Ties are broken by MRU, then by GUID comparison.
- if (score != other_score)
+ const double kEpsilon = 0.00001;
+ if (std::fabs(score - other_score) > kEpsilon)
return score > other_score;
if (use_date_ != other->use_date_)
@@ -77,7 +78,7 @@ double AutofillDataModel::GetFrecencyScore(base::Time time) const {
}
bool AutofillDataModel::IsDeletable() const {
- return use_date_ < AutofillClock::Now() - kDisusedDataModelDeletionTimeDelta;
+ return IsAutofillEntryWithUseDateDeletable(use_date_);
}
AutofillDataModel::ValidityState AutofillDataModel::GetValidityState(
diff --git a/chromium/components/autofill/core/browser/autofill_data_model.h b/chromium/components/autofill/core/browser/autofill_data_model.h
index 07fd92b828d..76909201239 100644
--- a/chromium/components/autofill/core/browser/autofill_data_model.h
+++ b/chromium/components/autofill/core/browser/autofill_data_model.h
@@ -103,6 +103,12 @@ class AutofillDataModel : public FormGroup {
// the subject of user interaction (usually, when it's used to fill a form).
void RecordUse();
+ // Returns a score based on both the recency (relative to |time|) and
+ // frequency for the model. The score is a negative number where a higher
+ // value is more relevant. |time| is passed as a parameter to ensure
+ // consistent results.
+ double GetFrecencyScore(base::Time time) const;
+
private:
// A globally unique ID for this object.
std::string guid_;
@@ -125,12 +131,6 @@ class AutofillDataModel : public FormGroup {
// The last time data in the model was modified, rounded in seconds. Any
// change should use set_previous_modification_date()
base::Time modification_date_;
-
- // Returns a score based on both the recency (relative to |time|) and
- // frequency for the model. The score is a negative number where a higher
- // value is more relevant. |time| is passed as a parameter to ensure
- // consistent results.
- double GetFrecencyScore(base::Time time) const;
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_data_util.cc b/chromium/components/autofill/core/browser/autofill_data_util.cc
index 542571769a6..5b530a04942 100644
--- a/chromium/components/autofill/core/browser/autofill_data_util.cc
+++ b/chromium/components/autofill/core/browser/autofill_data_util.cc
@@ -15,6 +15,7 @@
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
@@ -26,7 +27,13 @@
namespace autofill {
namespace data_util {
+using bit_field_type_groups::kAddress;
+using bit_field_type_groups::kEmail;
+using bit_field_type_groups::kName;
+using bit_field_type_groups::kPhone;
+
namespace {
+
// Mappings from Chrome card networks to Payment Request API basic card payment
// spec networks and icons. Note that "generic" is not in the spec.
// https://w3c.github.io/webpayments-methods-card/#method-id
@@ -242,6 +249,47 @@ bool SplitCJKName(const std::vector<base::StringPiece16>& name_tokens,
} // namespace
+bool ContainsName(uint32_t groups) {
+ return groups & kName;
+}
+
+bool ContainsAddress(uint32_t groups) {
+ return groups & kAddress;
+}
+
+bool ContainsEmail(uint32_t groups) {
+ return groups & kEmail;
+}
+
+bool ContainsPhone(uint32_t groups) {
+ return groups & kPhone;
+}
+
+uint32_t DetermineGroups(const std::vector<ServerFieldType>& types) {
+ uint32_t group_bitmask = 0;
+ for (const ServerFieldType& type : types) {
+ const FieldTypeGroup group =
+ AutofillType(AutofillType(type).GetStorableType()).group();
+ switch (group) {
+ case autofill::NAME:
+ group_bitmask |= kName;
+ break;
+ case autofill::ADDRESS_HOME:
+ group_bitmask |= kAddress;
+ break;
+ case autofill::EMAIL:
+ group_bitmask |= kEmail;
+ break;
+ case autofill::PHONE_HOME:
+ group_bitmask |= kPhone;
+ break;
+ default:
+ break;
+ }
+ }
+ return group_bitmask;
+}
+
std::string TruncateUTF8(const std::string& data) {
std::string trimmed_value;
base::TruncateUTF8ToByteSize(data, AutofillTable::kMaxDataLength,
diff --git a/chromium/components/autofill/core/browser/autofill_data_util.h b/chromium/components/autofill/core/browser/autofill_data_util.h
index ee3ede76fc8..ba8f55f0fdc 100644
--- a/chromium/components/autofill/core/browser/autofill_data_util.h
+++ b/chromium/components/autofill/core/browser/autofill_data_util.h
@@ -6,6 +6,7 @@
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_DATA_UTIL_H_
#include <string>
+#include <vector>
#include "base/strings/string16.h"
#include "base/strings/string_piece_forward.h"
@@ -23,6 +24,39 @@ struct NameParts {
base::string16 family;
};
+namespace bit_field_type_groups {
+
+// Bits for FieldTypeGroup options.
+// The form has a field associated with the NAME_HOME or NAME_BILLING
+// FieldTypeGroups.
+constexpr uint32_t kName = 1 << 0;
+// The form has a field associated with the ADDRESS_HOME or ADDRESS_BILLING
+// FieldTypeGroups.
+constexpr uint32_t kAddress = 1 << 1;
+// The form has a field associated with the EMAIL FieldTypeGroup.
+constexpr uint32_t kEmail = 1 << 2;
+// The form has a field associated with the PHONE_HOME or PHONE_BILLING
+// FieldTypeGroups.
+constexpr uint32_t kPhone = 1 << 3;
+
+} // namespace bit_field_type_groups
+
+// Returns true if kName is set in |groups|.
+bool ContainsName(uint32_t groups);
+
+// Returns true if kAddress is set in |groups|.
+bool ContainsAddress(uint32_t groups);
+
+// Returns true if kEmail is set in |groups|.
+bool ContainsEmail(uint32_t groups);
+
+// Returns true if kPhone is set in |groups|.
+bool ContainsPhone(uint32_t groups);
+
+// 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>& types);
+
// Truncates a string to the nearest UTF-8 character that will leave
// the string less than or equal to the specified byte size.
std::string TruncateUTF8(const std::string& data);
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 9e23fc158a4..b6c34b64afe 100644
--- a/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_download_manager_unittest.cc
@@ -1525,7 +1525,7 @@ TEST_P(AutofillQueryTest, ExpiredCacheInResponse) {
TEST_P(AutofillQueryTest, RichMetadata_Enabled) {
// Initialize a form. Note that this state is post-parse.
FormData form;
- form.origin = GURL("https://origin.com");
+ form.url = GURL("https://origin.com");
form.action = GURL("https://origin.com/submit-me");
form.id_attribute = UTF8ToUTF16("form-id-attribute");
form.name_attribute = UTF8ToUTF16("form-name-attribute");
@@ -1625,7 +1625,7 @@ TEST_P(AutofillQueryTest, RichMetadata_Enabled) {
TEST_P(AutofillQueryTest, RichMetadata_Disabled) {
// Initialize a form. Note that this state is post-parse.
FormData form;
- form.origin = GURL("https://origin.com");
+ form.url = GURL("https://origin.com");
form.action = GURL("https://origin.com/submit-me");
form.id_attribute = UTF8ToUTF16("form-id-attribute");
form.name_attribute = UTF8ToUTF16("form-name-attribute");
@@ -1715,7 +1715,7 @@ TEST_P(AutofillUploadTest, RichMetadata) {
local_feature.InitAndEnableFeature(features::kAutofillMetadataUploads);
FormData form;
- form.origin = GURL("https://origin.com");
+ form.url = GURL("https://origin.com");
form.action = GURL("https://origin.com/submit-me");
form.id_attribute = UTF8ToUTF16("form-id_attribute");
form.name_attribute = UTF8ToUTF16("form-id_attribute");
diff --git a/chromium/components/autofill/core/browser/autofill_experiments.cc b/chromium/components/autofill/core/browser/autofill_experiments.cc
index ffc1f9c2c89..15d85bf9bed 100644
--- a/chromium/components/autofill/core/browser/autofill_experiments.cc
+++ b/chromium/components/autofill/core/browser/autofill_experiments.cc
@@ -12,8 +12,12 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/payments/payments_util.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/suggestion.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/prefs/pref_service.h"
@@ -29,22 +33,31 @@
namespace autofill {
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-const base::Feature kAutofillDropdownLayoutExperiment{
- "AutofillDropdownLayout", base::FEATURE_DISABLED_BY_DEFAULT};
-const char kAutofillDropdownLayoutParameterName[] = "variant";
-const char kAutofillDropdownLayoutParameterLeadingIcon[] = "leading-icon";
-const char kAutofillDropdownLayoutParameterTrailingIcon[] = "trailing-icon";
-const char kAutofillDropdownLayoutParameterTwoLinesLeadingIcon[] =
- "two-lines-leading-icon";
-#endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-
bool IsCreditCardUploadEnabled(const PrefService* pref_service,
const syncer::SyncService* sync_service,
- const std::string& user_email) {
- if (!sync_service || sync_service->GetAuthError().IsPersistentError() ||
- !sync_service->GetActiveDataTypes().Has(syncer::AUTOFILL_WALLET_DATA)) {
+ const std::string& user_email,
+ const AutofillSyncSigninState sync_state) {
+ if (!sync_service) {
// If credit card sync is not active, we're not offering to upload cards.
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::SYNC_SERVICE_NULL,
+ sync_state);
+ return false;
+ }
+
+ if (sync_service->GetAuthError().IsPersistentError()) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_PERSISTENT_AUTH_ERROR,
+ sync_state);
+ return false;
+ }
+
+ if (!sync_service->GetActiveDataTypes().Has(syncer::AUTOFILL_WALLET_DATA)) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_MISSING_AUTOFILL_WALLET_DATA_ACTIVE_TYPE,
+ sync_state);
return false;
}
@@ -52,6 +65,10 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
if (!sync_service->GetActiveDataTypes().Has(syncer::AUTOFILL_PROFILE)) {
// In full sync mode, we only allow card upload when addresses are also
// active, because we upload potential billing addresses with the card.
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_MISSING_AUTOFILL_PROFILE_ACTIVE_TYPE,
+ sync_state);
return false;
}
} else {
@@ -63,6 +80,10 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
features::kAutofillEnableAccountWalletStorageUpload)) {
// We're not enabling uploads in the account wallet mode, so suppress
// the upload prompt.
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::
+ ACCOUNT_WALLET_STORAGE_UPLOAD_DISABLED,
+ sync_state);
return false;
}
}
@@ -71,21 +92,37 @@ 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->GetUserSettings()->IsUsingSecondaryPassphrase())
+ if (sync_service->GetUserSettings()->IsUsingSecondaryPassphrase()) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::
+ USING_SECONDARY_SYNC_PASSPHRASE,
+ sync_state);
return false;
+ }
// Don't offer upload for users that are only syncing locally, since they
// won't receive the cards back from Google Payments.
- if (sync_service->IsLocalSyncEnabled())
+ if (sync_service->IsLocalSyncEnabled()) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::LOCAL_SYNC_ENABLED,
+ sync_state);
return false;
+ }
// Check Payments integration user setting.
- if (!prefs::IsPaymentsIntegrationEnabled(pref_service))
+ if (!prefs::IsPaymentsIntegrationEnabled(pref_service)) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::PAYMENTS_INTEGRATION_DISABLED,
+ sync_state);
return false;
+ }
// Check that the user is logged into a supported domain.
- if (user_email.empty())
+ if (user_email.empty()) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::EMAIL_EMPTY, sync_state);
return false;
+ }
std::string domain = gaia::ExtractDomainName(user_email);
// If the "allow all email domains" flag is off, restrict credit card upload
@@ -98,10 +135,64 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
!(domain == "googlemail.com" || domain == "gmail.com" ||
domain == "google.com" || domain == "chromium.org" ||
domain == "example.com")) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::EMAIL_DOMAIN_NOT_SUPPORTED,
+ sync_state);
return false;
}
- return base::FeatureList::IsEnabled(features::kAutofillUpstream);
+ if (!base::FeatureList::IsEnabled(features::kAutofillUpstream)) {
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::AUTOFILL_UPSTREAM_DISABLED,
+ sync_state);
+ return false;
+ }
+
+ AutofillMetrics::LogCardUploadEnabledMetric(
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED,
+ sync_state);
+ return true;
+}
+
+bool IsCreditCardMigrationEnabled(PersonalDataManager* personal_data_manager,
+ PrefService* pref_service,
+ syncer::SyncService* sync_service,
+ bool is_test_mode) {
+ // Confirm that experiment flags are enabled.
+ if (features::GetLocalCardMigrationExperimentalFlag() ==
+ features::LocalCardMigrationExperimentalFlag::kMigrationDisabled) {
+ return false;
+ }
+
+ // If |is_test_mode| is set, assume we are in a browsertest and
+ // credit card upload should be enabled by default to fix flaky
+ // local card migration browsertests.
+ if (!is_test_mode &&
+ !IsCreditCardUploadEnabled(
+ pref_service, sync_service,
+ personal_data_manager->GetAccountInfoForPaymentsServer().email,
+ personal_data_manager->GetSyncSigninState())) {
+ return false;
+ }
+
+ if (!autofill::payments::HasGooglePaymentsAccount(personal_data_manager))
+ return false;
+
+ switch (personal_data_manager->GetSyncSigninState()) {
+ case AutofillSyncSigninState::kSignedOut:
+ case AutofillSyncSigninState::kSignedIn:
+ case AutofillSyncSigninState::kSyncPaused:
+ return false;
+ case AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled:
+ return base::FeatureList::IsEnabled(
+ features::kAutofillEnableLocalCardMigrationForNonSyncUser);
+ case AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled:
+ return true;
+ case AutofillSyncSigninState::kNumSyncStates:
+ break;
+ }
+ NOTREACHED();
+ return false;
}
bool IsInAutofillSuggestionsDisabledExperiment() {
@@ -110,14 +201,6 @@ bool IsInAutofillSuggestionsDisabledExperiment() {
return group_name == "Disabled";
}
-bool IsAutofillCreditCardAssistEnabled() {
-#if !defined(OS_ANDROID) && !defined(OS_IOS)
- return false;
-#else
- return base::FeatureList::IsEnabled(features::kAutofillCreditCardAssist);
-#endif
-}
-
features::LocalCardMigrationExperimentalFlag
GetLocalCardMigrationExperimentalFlag() {
if (!base::FeatureList::IsEnabled(
@@ -182,30 +265,4 @@ bool ShouldUseActiveSignedInAccount() {
features::kAutofillGetPaymentsIdentityFromSync);
}
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-ForcedPopupLayoutState GetForcedPopupLayoutState() {
- if (!base::FeatureList::IsEnabled(
- autofill::kAutofillDropdownLayoutExperiment))
- return ForcedPopupLayoutState::kDefault;
-
- std::string param = base::GetFieldTrialParamValueByFeature(
- kAutofillDropdownLayoutExperiment, kAutofillDropdownLayoutParameterName);
-
- if (param == kAutofillDropdownLayoutParameterLeadingIcon) {
- return ForcedPopupLayoutState::kLeadingIcon;
- } else if (param == kAutofillDropdownLayoutParameterTrailingIcon) {
- return ForcedPopupLayoutState::kTrailingIcon;
- } else if (param ==
- autofill::kAutofillDropdownLayoutParameterTwoLinesLeadingIcon) {
- return ForcedPopupLayoutState::kTwoLinesLeadingIcon;
- } else if (param.empty()) {
- return ForcedPopupLayoutState::kDefault;
- }
-
- // Unknown parameter value.
- NOTREACHED();
- return ForcedPopupLayoutState::kDefault;
-}
-#endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_experiments.h b/chromium/components/autofill/core/browser/autofill_experiments.h
index d4247999259..c4a32743e09 100644
--- a/chromium/components/autofill/core/browser/autofill_experiments.h
+++ b/chromium/components/autofill/core/browser/autofill_experiments.h
@@ -9,34 +9,31 @@
#include "base/strings/string16.h"
#include "build/build_config.h"
+#include "components/autofill/core/browser/sync_utils.h"
class PrefService;
-namespace base {
-struct Feature;
-}
-
namespace syncer {
class SyncService;
}
namespace autofill {
-// Parameterized Features (grouped with parameter name and options)
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-extern const base::Feature kAutofillDropdownLayoutExperiment;
-extern const char kAutofillDropdownLayoutParameterName[];
-extern const char kAutofillDropdownLayoutParameterLeadingIcon[];
-extern const char kAutofillDropdownLayoutParameterTrailingIcon[];
-extern const char kAutofillDropdownLayoutParameterTwoLinesLeadingIcon[];
-#endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
+class PersonalDataManager;
// Returns true if uploading credit cards to Wallet servers is enabled. This
// requires the appropriate flags and user settings to be true and the user to
// be a member of a supported domain.
bool IsCreditCardUploadEnabled(const PrefService* pref_service,
const syncer::SyncService* sync_service,
- const std::string& user_email);
+ const std::string& user_email,
+ const AutofillSyncSigninState sync_state);
+
+// Returns true if autofill local card migration flow is enabled.
+bool IsCreditCardMigrationEnabled(PersonalDataManager* personal_data_manager,
+ PrefService* pref_service,
+ syncer::SyncService* sync_service,
+ bool is_test_mode);
// Returns true if autofill suggestions are disabled via experiment. The
// disabled experiment isn't the same as disabling autofill completely since we
@@ -44,9 +41,6 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
// disables providing suggestions.
bool IsInAutofillSuggestionsDisabledExperiment();
-// Returns whether the Autofill credit card assist infobar should be shown.
-bool IsAutofillCreditCardAssistEnabled();
-
// Returns whether locally saving card when credit card upload succeeds should
// be disabled.
bool IsAutofillNoLocalSaveOnUploadSuccessExperimentEnabled();
@@ -59,22 +53,6 @@ bool OfferStoreUnmaskedCards(bool is_off_the_record);
// Returns whether the account of the active signed-in user should be used.
bool ShouldUseActiveSignedInAccount();
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-enum class ForcedPopupLayoutState {
- kDefault, // No popup layout forced by experiment.
- kLeadingIcon, // Experiment forces leading (left in LTR) icon layout.
- kTrailingIcon, // Experiment forces trailing (right in LTR) icon layout.
- kTwoLinesLeadingIcon, // Experiment forces leading (left in LTR) icon layout.
- // with two lines display.
-};
-
-// Returns kDefault if no experimental behavior is enabled for
-// kAutofillDropdownLayoutExperiment; returns kLeftIcon or kRightIcon
-// if the experiment param matches kAutofillDropdownLayoutParameterLeadingIcon
-// or kAutofillDropdownLayoutParameterTrailingIcon, respectively.
-ForcedPopupLayoutState GetForcedPopupLayoutState();
-#endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
-
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_
diff --git a/chromium/components/autofill/core/browser/autofill_experiments_unittest.cc b/chromium/components/autofill/core/browser/autofill_experiments_unittest.cc
index a23650fba78..b8ff2be732b 100644
--- a/chromium/components/autofill/core/browser/autofill_experiments_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_experiments_unittest.cc
@@ -4,8 +4,11 @@
#include "components/autofill/core/browser/autofill_experiments.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
@@ -25,71 +28,147 @@ class AutofillExperimentsTest : public testing::Test {
prefs::kAutofillWalletImportEnabled, true);
}
- bool IsCreditCardUploadEnabled() {
- return IsCreditCardUploadEnabled("john.smith@gmail.com");
+ bool IsCreditCardUploadEnabled(const AutofillSyncSigninState sync_state) {
+ return IsCreditCardUploadEnabled("john.smith@gmail.com", sync_state);
}
- bool IsCreditCardUploadEnabled(const std::string& user_email) {
+ bool IsCreditCardUploadEnabled(const std::string& user_email,
+ const AutofillSyncSigninState sync_state) {
return autofill::IsCreditCardUploadEnabled(&pref_service_, &sync_service_,
- user_email);
+ user_email, sync_state);
}
base::test::ScopedFeatureList scoped_feature_list_;
TestingPrefServiceSimple pref_service_;
syncer::TestSyncService sync_service_;
+ base::HistogramTester histogram_tester;
};
-TEST_F(AutofillExperimentsTest, DenyUpload_FeatureEnabled) {
+// Testing each scenario, followed by logging the metrics for various
+// success and failure scenario of IsCreditCardUploadEnabled(). Every scenario
+// should also be associated with logging of a metric so it's easy to analyze
+// the results.
+TEST_F(AutofillExperimentsTest, IsCardUploadEnabled_FeatureEnabled) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
- EXPECT_TRUE(IsCreditCardUploadEnabled());
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 1);
}
-TEST_F(AutofillExperimentsTest, DenyUpload_FeatureDisabled) {
+TEST_F(AutofillExperimentsTest, IsCardUploadEnabled_FeatureDisabled) {
scoped_feature_list_.InitAndDisableFeature(features::kAutofillUpstream);
- EXPECT_FALSE(IsCreditCardUploadEnabled());
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::AUTOFILL_UPSTREAM_DISABLED, 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::AUTOFILL_UPSTREAM_DISABLED, 1);
}
-TEST_F(AutofillExperimentsTest, DenyUpload_AuthError) {
+TEST_F(AutofillExperimentsTest, IsCardUploadEnabled_AuthError) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
sync_service_.SetAuthError(
GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
- EXPECT_FALSE(IsCreditCardUploadEnabled());
+ EXPECT_FALSE(IsCreditCardUploadEnabled(AutofillSyncSigninState::kSyncPaused));
+ histogram_tester.ExpectUniqueSample("Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_PERSISTENT_AUTH_ERROR,
+ 1);
+ histogram_tester.ExpectUniqueSample("Autofill.CardUploadEnabled.SyncPaused",
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_PERSISTENT_AUTH_ERROR,
+ 1);
}
-TEST_F(AutofillExperimentsTest, DenyUpload_SyncDoesNotHaveWalletDataType) {
+TEST_F(AutofillExperimentsTest,
+ IsCardUploadEnabled_SyncDoesNotHaveAutofillWalletDataActiveType) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
sync_service_.SetActiveDataTypes(syncer::ModelTypeSet());
- EXPECT_FALSE(IsCreditCardUploadEnabled());
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_MISSING_AUTOFILL_WALLET_DATA_ACTIVE_TYPE,
+ 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_MISSING_AUTOFILL_WALLET_DATA_ACTIVE_TYPE,
+ 1);
}
TEST_F(AutofillExperimentsTest,
- DenyUpload_FullSyncDoesNotHaveAutofillProfileActiveDataType) {
+ IsCardUploadEnabled_SyncDoesNotHaveAutofillProfileActiveType) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
sync_service_.SetActiveDataTypes(
syncer::ModelTypeSet(syncer::AUTOFILL_WALLET_DATA));
- EXPECT_FALSE(IsCreditCardUploadEnabled());
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_MISSING_AUTOFILL_PROFILE_ACTIVE_TYPE,
+ 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::
+ SYNC_SERVICE_MISSING_AUTOFILL_PROFILE_ACTIVE_TYPE,
+ 1);
}
TEST_F(AutofillExperimentsTest,
- DenyUpload_SyncServiceUsingSecondaryPassphrase) {
+ IsCardUploadEnabled_SyncServiceUsingSecondaryPassphrase) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
sync_service_.SetIsUsingSecondaryPassphrase(true);
- EXPECT_FALSE(IsCreditCardUploadEnabled());
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::USING_SECONDARY_SYNC_PASSPHRASE,
+ 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::USING_SECONDARY_SYNC_PASSPHRASE,
+ 1);
}
TEST_F(AutofillExperimentsTest,
- DenyUpload_AutofillWalletImportEnabledPrefIsDisabled) {
+ IsCardUploadEnabled_AutofillWalletImportEnabledPrefIsDisabled) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
prefs::SetPaymentsIntegrationEnabled(&pref_service_, false);
- EXPECT_FALSE(IsCreditCardUploadEnabled());
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::PAYMENTS_INTEGRATION_DISABLED,
+ 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::PAYMENTS_INTEGRATION_DISABLED,
+ 1);
}
-TEST_F(AutofillExperimentsTest, DenyUpload_EmptyUserEmail) {
+TEST_F(AutofillExperimentsTest, IsCardUploadEnabled_EmptyUserEmail) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
- EXPECT_FALSE(IsCreditCardUploadEnabled(""));
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ "", AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::EMAIL_EMPTY, 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::EMAIL_EMPTY, 1);
}
-TEST_F(AutofillExperimentsTest, AllowUpload_TransportModeOnly) {
+TEST_F(AutofillExperimentsTest, IsCardUploadEnabled_TransportModeOnly) {
scoped_feature_list_.InitWithFeatures(
/*enable_features=*/{features::kAutofillUpstream,
features::kAutofillEnableAccountWalletStorage},
@@ -98,11 +177,19 @@ TEST_F(AutofillExperimentsTest, AllowUpload_TransportModeOnly) {
// (if allowed).
sync_service_.SetIsAuthenticatedAccountPrimary(false);
- EXPECT_TRUE(IsCreditCardUploadEnabled("john.smith@gmail.com"));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "john.smith@gmail.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 1);
}
TEST_F(AutofillExperimentsTest,
- DenyUpload_TransportSyncDoesNotHaveUploadEnabled) {
+ IsCardUploadEnabled_TransportSyncDoesNotHaveUploadEnabled) {
scoped_feature_list_.InitWithFeatures(
/*enable_features=*/{features::kAutofillUpstream,
features::kAutofillEnableAccountWalletStorage},
@@ -112,11 +199,23 @@ TEST_F(AutofillExperimentsTest,
// (if allowed).
sync_service_.SetIsAuthenticatedAccountPrimary(false);
- EXPECT_FALSE(IsCreditCardUploadEnabled());
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::
+ ACCOUNT_WALLET_STORAGE_UPLOAD_DISABLED,
+ 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::
+ ACCOUNT_WALLET_STORAGE_UPLOAD_DISABLED,
+ 1);
}
-TEST_F(AutofillExperimentsTest,
- AllowUpload_TransportSyncDoesNotHaveAutofillProfileActiveDataType) {
+TEST_F(
+ AutofillExperimentsTest,
+ IsCardUploadEnabled_TransportSyncDoesNotHaveAutofillProfileActiveDataType) {
scoped_feature_list_.InitWithFeatures(
/*enable_features=*/{features::kAutofillUpstream,
features::kAutofillEnableAccountWalletStorage},
@@ -130,35 +229,85 @@ TEST_F(AutofillExperimentsTest,
sync_service_.SetActiveDataTypes(
syncer::ModelTypeSet(syncer::AUTOFILL_WALLET_DATA));
- EXPECT_TRUE(IsCreditCardUploadEnabled());
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 1);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 1);
}
-TEST_F(AutofillExperimentsTest, AllowUpload_UserEmailWithGoogleDomain) {
+TEST_F(AutofillExperimentsTest, IsCardUploadEnabled_UserEmailWithGoogleDomain) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
- EXPECT_TRUE(IsCreditCardUploadEnabled("john.smith@gmail.com"));
- EXPECT_TRUE(IsCreditCardUploadEnabled("googler@google.com"));
- EXPECT_TRUE(IsCreditCardUploadEnabled("old.school@googlemail.com"));
- EXPECT_TRUE(IsCreditCardUploadEnabled("code.committer@chromium.org"));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "john.smith@gmail.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "googler@google.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "old.school@googlemail.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "code.committer@chromium.org",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 4);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 4);
}
-TEST_F(AutofillExperimentsTest, DenyUpload_UserEmailWithNonGoogleDomain) {
+TEST_F(AutofillExperimentsTest,
+ IsCardUploadEnabled_UserEmailWithNonGoogleDomain) {
scoped_feature_list_.InitAndEnableFeature(features::kAutofillUpstream);
- EXPECT_FALSE(IsCreditCardUploadEnabled("cool.user@hotmail.com"));
- EXPECT_FALSE(IsCreditCardUploadEnabled("john.smith@johnsmith.com"));
- EXPECT_FALSE(IsCreditCardUploadEnabled("fake.googler@google.net"));
- EXPECT_FALSE(IsCreditCardUploadEnabled("fake.committer@chromium.com"));
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ "cool.user@hotmail.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ "john.smith@johnsmith.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ "fake.googler@google.net",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_FALSE(IsCreditCardUploadEnabled(
+ "fake.committer@chromium.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::EMAIL_DOMAIN_NOT_SUPPORTED, 4);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::EMAIL_DOMAIN_NOT_SUPPORTED, 4);
}
TEST_F(AutofillExperimentsTest,
- AllowUpload_UserEmailWithNonGoogleDomainIfExperimentEnabled) {
+ IsCardUploadEnabled_UserEmailWithNonGoogleDomainIfExperimentEnabled) {
scoped_feature_list_.InitWithFeatures(
{features::kAutofillUpstream,
features::kAutofillUpstreamAllowAllEmailDomains},
{});
- EXPECT_TRUE(IsCreditCardUploadEnabled("cool.user@hotmail.com"));
- EXPECT_TRUE(IsCreditCardUploadEnabled("john.smith@johnsmith.com"));
- EXPECT_TRUE(IsCreditCardUploadEnabled("fake.googler@google.net"));
- EXPECT_TRUE(IsCreditCardUploadEnabled("fake.committer@chromium.com"));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "cool.user@hotmail.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "john.smith@johnsmith.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "fake.googler@google.net",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ EXPECT_TRUE(IsCreditCardUploadEnabled(
+ "fake.committer@chromium.com",
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled));
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 4);
+ histogram_tester.ExpectUniqueSample(
+ "Autofill.CardUploadEnabled.SignedInAndSyncFeatureEnabled",
+ AutofillMetrics::CardUploadEnabledMetric::CARD_UPLOAD_ENABLED, 4);
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/autofill_external_delegate.cc b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
index 0024f2d615f..4b631efce6e 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate.cc
@@ -22,7 +22,7 @@
#include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/popup_item_ids.h"
-#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "components/strings/grit/components_strings.h"
@@ -207,6 +207,7 @@ void AutofillExternalDelegate::DidAcceptSuggestion(const base::string16& value,
manager_->ShowAutofillSettings(popup_type_ == PopupType::kCreditCards);
} else if (identifier == POPUP_ITEM_ID_CLEAR_FORM) {
// User selected 'Clear form'.
+ AutofillMetrics::LogAutofillFormCleared();
driver_->RendererShouldClearFilledSection();
} else if (identifier == POPUP_ITEM_ID_PASSWORD_ENTRY ||
identifier == POPUP_ITEM_ID_USERNAME_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 3e7d77e2a14..8974bfedfb1 100644
--- a/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -25,6 +25,7 @@
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
diff --git a/chromium/components/autofill/core/browser/autofill_handler.cc b/chromium/components/autofill/core/browser/autofill_handler.cc
index a495cefa853..f0af93bb2fa 100644
--- a/chromium/components/autofill/core/browser/autofill_handler.cc
+++ b/chromium/components/autofill/core/browser/autofill_handler.cc
@@ -7,6 +7,7 @@
#include "base/containers/adapters.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/common/autofill_data_validation.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/signatures_util.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -79,8 +80,29 @@ void AutofillHandler::OnFormsSeen(const std::vector<FormData>& forms,
std::set<FormSignature> new_form_signatures;
for (const FormData& form : forms) {
const auto parse_form_start_time = TimeTicks::Now();
+ FormStructure* cached_form_structure = nullptr;
FormStructure* form_structure = nullptr;
- if (!ParseForm(form, /*cached_form=*/nullptr, &form_structure))
+ // Try to find the FormStructure that corresponds to |form| if the form
+ // contains credit card fields only.
+ // |cached_form_structure| may still be nullptr after this call.
+ if (base::FeatureList::IsEnabled(features::kAutofillImportDynamicForms)) {
+ ignore_result(FindCachedForm(form, &cached_form_structure));
+ bool only_contains_credit_card_fields = true;
+ if (cached_form_structure) {
+ for (const FormType& form_type :
+ cached_form_structure->GetFormTypes()) {
+ if (form_type != CREDIT_CARD_FORM) {
+ only_contains_credit_card_fields = false;
+ break;
+ }
+ }
+ }
+ if (!only_contains_credit_card_fields) {
+ cached_form_structure = nullptr;
+ }
+ }
+
+ if (!ParseForm(form, cached_form_structure, &form_structure))
continue;
DCHECK(form_structure);
new_form_signatures.insert(form_structure->form_signature());
@@ -261,8 +283,14 @@ bool AutofillHandler::ParseForm(const FormData& form,
// We need to keep the server data if available. We need to use them while
// determining the heuristics.
form_structure->RetrieveFromCache(*cached_form,
- /*apply_is_autofilled=*/true,
+ /*should_keep_cached_value=*/true,
/*only_server_and_autofill_state=*/true);
+ if (observer_for_testing_)
+ observer_for_testing_->OnFormParsed();
+
+ if (form_structure.get()->value_from_dynamic_change_form()) {
+ value_from_dynamic_change_form_ = true;
+ }
}
form_structure->DetermineHeuristicTypes();
diff --git a/chromium/components/autofill/core/browser/autofill_handler.h b/chromium/components/autofill/core/browser/autofill_handler.h
index 16f06b44368..b1744e84b57 100644
--- a/chromium/components/autofill/core/browser/autofill_handler.h
+++ b/chromium/components/autofill/core/browser/autofill_handler.h
@@ -37,6 +37,13 @@ class AutofillHandler {
DISABLE_AUTOFILL_DOWNLOAD_MANAGER,
};
+ // An observer class used by browsertests that gets notified whenever
+ // particular actions occur.
+ class ObserverForTest {
+ public:
+ virtual void OnFormParsed() = 0;
+ };
+
using FormStructureMap =
std::map<FormSignature, std::unique_ptr<FormStructure>>;
@@ -126,6 +133,10 @@ class AutofillHandler {
// Returns the number of forms this Autofill handler is aware of.
size_t NumFormsDetected() const { return form_structures_.size(); }
+ void SetEventObserverForTesting(ObserverForTest* observer) {
+ observer_for_testing_ = observer;
+ }
+
// Returns the present form structures seen by Autofill handler.
const FormStructureMap& form_structures() const { return form_structures_; }
@@ -190,6 +201,8 @@ class AutofillHandler {
const FormStructure* cached_form,
FormStructure** parsed_form_structure);
+ bool value_from_dynamic_change_form_ = false;
+
AutofillDriver* driver() { return driver_; }
FormStructureMap* mutable_form_structures() { return &form_structures_; }
@@ -202,6 +215,9 @@ class AutofillHandler {
// Our copy of the form data.
FormStructureMap form_structures_;
+ // Will be not null only for |SaveCardBubbleViewsFullFormBrowserTest|.
+ ObserverForTest* observer_for_testing_ = nullptr;
+
DISALLOW_COPY_AND_ASSIGN(AutofillHandler);
};
diff --git a/chromium/components/autofill/core/browser/autofill_manager.cc b/chromium/components/autofill/core/browser/autofill_manager.cc
index dcc247b97d0..94a84dc98ea 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager.cc
@@ -65,6 +65,7 @@
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_data_validation.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -736,8 +737,7 @@ void AutofillManager::FillOrPreviewProfileForm(
profile, *form_structure, *autofill_field, sync_state_);
// Set up the information needed for an eventual refill of this form.
- if (base::FeatureList::IsEnabled(features::kAutofillDynamicForms) &&
- !form_structure->GetIdentifierForRefill().empty()) {
+ if (!form_structure->GetIdentifierForRefill().empty()) {
auto& entry =
filling_contexts_map_[form_structure->GetIdentifierForRefill()];
auto filling_context = std::make_unique<FillingContext>();
@@ -1402,7 +1402,6 @@ void AutofillManager::FillOrPreviewDataModelForm(
if (itr != filling_contexts_map_.end())
filling_context = itr->second.get();
bool could_attempt_refill =
- base::FeatureList::IsEnabled(features::kAutofillDynamicForms) &&
filling_context != nullptr && !filling_context->attempted_refill &&
!is_refill && !is_credit_card;
@@ -1512,8 +1511,12 @@ std::unique_ptr<FormStructure> AutofillManager::ValidateSubmittedForm(
auto submitted_form = std::make_unique<FormStructure>(form);
submitted_form->RetrieveFromCache(*cached_submitted_form,
- /*apply_is_autofilled=*/false,
+ /*should_keep_cached_value=*/false,
/*only_server_and_autofill_state=*/false);
+ if (value_from_dynamic_change_form_) {
+ submitted_form->set_value_from_dynamic_change_form(true);
+ }
+
return submitted_form;
}
@@ -2014,9 +2017,6 @@ void AutofillManager::FillFieldWithValue(AutofillField* autofill_field,
}
bool AutofillManager::ShouldTriggerRefill(const FormStructure& form_structure) {
- if (!base::FeatureList::IsEnabled(features::kAutofillDynamicForms))
- return false;
-
// Should not refill if a form with the same name has not been filled before.
auto itr =
filling_contexts_map_.find(form_structure.GetIdentifierForRefill());
diff --git a/chromium/components/autofill/core/browser/autofill_manager.h b/chromium/components/autofill/core/browser/autofill_manager.h
index e9871cd2c89..c6aee10ea77 100644
--- a/chromium/components/autofill/core/browser/autofill_manager.h
+++ b/chromium/components/autofill/core/browser/autofill_manager.h
@@ -26,11 +26,11 @@
#include "components/autofill/core/browser/autofill_driver.h"
#include "components/autofill/core/browser/autofill_handler.h"
#include "components/autofill/core/browser/autofill_metrics.h"
-#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/card_unmask_delegate.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"
diff --git a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
index 20c8ed86951..b5488cb9d16 100644
--- a/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -36,6 +36,7 @@
#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_credit_card_save_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/popup_item_ids.h"
@@ -46,7 +47,6 @@
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/browser/test_autofill_external_delegate.h"
#include "components/autofill/core/browser/test_autofill_manager.h"
-#include "components/autofill/core/browser/test_credit_card_save_manager.h"
#include "components/autofill/core/browser/test_form_data_importer.h"
#include "components/autofill/core/browser/test_form_structure.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
@@ -54,6 +54,7 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -175,10 +176,10 @@ void ExpectFilledForm(int page_id,
EXPECT_EQ(expected_page_id, page_id);
EXPECT_EQ(ASCIIToUTF16("MyForm"), filled_form.name);
if (has_credit_card_fields) {
- EXPECT_EQ(GURL("https://myform.com/form.html"), filled_form.origin);
+ EXPECT_EQ(GURL("https://myform.com/form.html"), filled_form.url);
EXPECT_EQ(GURL("https://myform.com/submit.html"), filled_form.action);
} else {
- EXPECT_EQ(GURL("http://myform.com/form.html"), filled_form.origin);
+ EXPECT_EQ(GURL("http://myform.com/form.html"), filled_form.url);
EXPECT_EQ(GURL("http://myform.com/submit.html"), filled_form.action);
}
@@ -314,8 +315,7 @@ class AutofillManagerTest : public testing::Test {
payments::TestPaymentsClient* payments_client =
new payments::TestPaymentsClient(
autofill_driver_->GetURLLoaderFactory(),
- autofill_client_.GetPrefs(), autofill_client_.GetIdentityManager(),
- &personal_data_);
+ autofill_client_.GetIdentityManager(), &personal_data_);
autofill_client_.set_test_payments_client(
std::unique_ptr<payments::TestPaymentsClient>(payments_client));
TestCreditCardSaveManager* credit_card_save_manager =
@@ -485,10 +485,10 @@ class AutofillManagerTest : public testing::Test {
bool use_month_type) {
form->name = ASCIIToUTF16("MyForm");
if (is_https) {
- form->origin = GURL("https://myform.com/form.html");
+ form->url = GURL("https://myform.com/form.html");
form->action = GURL("https://myform.com/submit.html");
} else {
- form->origin = GURL("http://myform.com/form.html");
+ form->url = GURL("http://myform.com/form.html");
form->action = GURL("http://myform.com/submit.html");
}
@@ -687,7 +687,7 @@ TEST_F(AutofillManagerTest, OnFormsSeen_DifferentFormStructures) {
// Different form structure.
FormData form2;
form2.name = ASCIIToUTF16("MyForm");
- form2.origin = GURL("https://myform.com/form.html");
+ form2.url = GURL("https://myform.com/form.html");
form2.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First Name", "firstname", "", "text", &field);
@@ -717,7 +717,7 @@ TEST_F(AutofillManagerTest, OnFormsSeen_SendAutofillTypePredictionsToRenderer) {
FormFieldData field;
test::CreateTestFormField("Querty", "qwerty", "", "text", &field);
form2.name = ASCIIToUTF16("NonQueryable");
- form2.origin = form1.origin;
+ form2.url = form1.url;
form2.action = GURL("https://myform.com/submit.html");
form2.fields.push_back(field);
@@ -736,7 +736,7 @@ TEST_F(AutofillManagerTest, GetProfileSuggestions_UnrecognizedAttribute) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
// Set a valid autocomplete attribute for the first name.
@@ -782,7 +782,7 @@ TEST_F(AutofillManagerTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First Name", "firstname", "", "text", &field);
@@ -816,7 +816,7 @@ TEST_F(AutofillManagerTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First Name", "firstname", "", "text", &field);
@@ -851,7 +851,7 @@ TEST_F(AutofillManagerTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First Name", "firstname", "", "text", &field);
@@ -889,7 +889,7 @@ TEST_F(AutofillManagerTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First Name", "firstname", "", "text", &field);
@@ -924,7 +924,7 @@ TEST_F(AutofillManagerTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First Name", "firstname", "", "text", &field);
@@ -1075,7 +1075,7 @@ TEST_F(AutofillManagerTest, GetProfileSuggestions_UnknownFields) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
@@ -1716,7 +1716,7 @@ TEST_F(AutofillManagerTest, GetProfileSuggestions_ForPhonePrefixOrSuffix) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
struct {
@@ -2039,7 +2039,7 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_SplitName) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
@@ -2109,7 +2109,7 @@ TEST_F(AutofillManagerTest, FillAddressAndCreditCardForm) {
TEST_F(AutofillManagerTest, FillAddressForm_UnrecognizedAttribute) {
FormData address_form;
address_form.name = ASCIIToUTF16("MyForm");
- address_form.origin = GURL("https://myform.com/form.html");
+ address_form.url = GURL("https://myform.com/form.html");
address_form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
// Set a valid autocomplete attribute for the first name.
@@ -2155,7 +2155,7 @@ TEST_F(AutofillManagerTest, FillAddressForm_AutocompleteOffRespected) {
FormData address_form;
address_form.name = ASCIIToUTF16("MyForm");
- address_form.origin = GURL("https://myform.com/form.html");
+ address_form.url = GURL("https://myform.com/form.html");
address_form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First name", "firstname", "", "text", &field);
@@ -2213,7 +2213,7 @@ TEST_F(AutofillManagerTest, FillAddressForm_AutocompleteOffRespected) {
TEST_F(AutofillManagerTest, FillAddressForm_AutocompleteOffNotRespected) {
FormData address_form;
address_form.name = ASCIIToUTF16("MyForm");
- address_form.origin = GURL("https://myform.com/form.html");
+ address_form.url = GURL("https://myform.com/form.html");
address_form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First name", "firstname", "", "text", &field);
@@ -2249,11 +2249,62 @@ TEST_F(AutofillManagerTest, FillAddressForm_AutocompleteOffNotRespected) {
"text", response_data.fields[3]);
}
+// Test that if a company is of a format of a birthyear and the relevant feature
+// is enabled, we would not fill it.
+TEST_F(AutofillManagerTest, FillAddressForm_CompanyBirthyear) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeature(
+ features::kAutofillRejectCompanyBirthyear);
+
+ // Set up our form data.
+ FormData address_form;
+ address_form.name = ASCIIToUTF16("MyForm");
+ address_form.url = GURL("https://myform.com/form.html");
+ address_form.action = GURL("https://myform.com/submit.html");
+
+ FormFieldData field;
+ test::CreateTestFormField("First name", "firstname", "", "text", &field);
+ address_form.fields.push_back(field);
+ test::CreateTestFormField("Middle name", "middle", "", "text", &field);
+ address_form.fields.push_back(field);
+ test::CreateTestFormField("Last name", "lastname", "", "text", &field);
+ address_form.fields.push_back(field);
+ test::CreateTestFormField("Company", "company", "", "text", &field);
+ address_form.fields.push_back(field);
+
+ std::vector<FormData> address_forms(1, address_form);
+ FormsSeen(address_forms);
+
+ AutofillProfile profile;
+ const char guid[] = "00000000-0000-0000-0000-000000000123";
+ test::SetProfileInfo(&profile, "Elvis", "Aaron", "Presley",
+ "theking@gmail.com", "1987", "3734 Elvis Presley Blvd.",
+ "Apt. 10", "Memphis", "Tennessee", "38116", "US",
+ "12345678901");
+ profile.set_guid(guid);
+ personal_data_.AddProfile(profile);
+
+ int response_page_id = 0;
+ FormData response_data;
+ FillAutofillFormDataAndSaveResults(
+ kDefaultPageID, address_form, *address_form.fields.begin(),
+ MakeFrontendID(std::string(), guid), &response_page_id, &response_data);
+
+ // All the fields should be filled except the company.
+ ExpectFilledField("First name", "firstname", "Elvis", "text",
+ response_data.fields[0]);
+ ExpectFilledField("Middle name", "middle", "Aaron", "text",
+ response_data.fields[1]);
+ ExpectFilledField("Last name", "lastname", "Presley", "text",
+ response_data.fields[2]);
+ ExpectFilledField("Company", "company", "", "text", response_data.fields[3]);
+}
+
// Test that a field with a value equal to it's placeholder attribute is filled.
TEST_F(AutofillManagerTest, FillAddressForm_PlaceholderEqualsValue) {
FormData address_form;
address_form.name = ASCIIToUTF16("MyForm");
- address_form.origin = GURL("https://myform.com/form.html");
+ address_form.url = GURL("https://myform.com/form.html");
address_form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
// Set the same placeholder and value for each field.
@@ -2295,7 +2346,7 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_UnrecognizedAttribute) {
// Set up the form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
@@ -2372,7 +2423,7 @@ TEST_F(AutofillManagerTest, FillCreditCardForm_ExpiredCard) {
// Set up the form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
// Create a credit card form.
@@ -2426,7 +2477,7 @@ TEST_F(AutofillManagerTest, FillFormWithNonFocusableFields) {
// Create a form with both focusable and non-focusable fields.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
@@ -2553,7 +2604,7 @@ TEST_F(AutofillManagerTest, FillFormWithAuthorSpecifiedSections) {
// The billing section includes both address and credit card fields.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
@@ -2616,7 +2667,7 @@ TEST_F(AutofillManagerTest, FillFormWithAuthorSpecifiedSections) {
SCOPED_TRACE("Unnamed section");
EXPECT_EQ(kDefaultPageID, response_page_id);
EXPECT_EQ(ASCIIToUTF16("MyForm"), response_data.name);
- EXPECT_EQ(GURL("https://myform.com/form.html"), response_data.origin);
+ EXPECT_EQ(GURL("https://myform.com/form.html"), response_data.url);
EXPECT_EQ(GURL("https://myform.com/submit.html"), response_data.action);
ASSERT_EQ(11U, response_data.fields.size());
@@ -2647,7 +2698,7 @@ TEST_F(AutofillManagerTest, FillFormWithAuthorSpecifiedSections) {
SCOPED_TRACE("Billing address");
EXPECT_EQ(kPageID2, response_page_id);
EXPECT_EQ(ASCIIToUTF16("MyForm"), response_data.name);
- EXPECT_EQ(GURL("https://myform.com/form.html"), response_data.origin);
+ EXPECT_EQ(GURL("https://myform.com/form.html"), response_data.url);
EXPECT_EQ(GURL("https://myform.com/submit.html"), response_data.action);
ASSERT_EQ(11U, response_data.fields.size());
@@ -2677,7 +2728,7 @@ TEST_F(AutofillManagerTest, FillFormWithAuthorSpecifiedSections) {
SCOPED_TRACE("Credit card");
EXPECT_EQ(kPageID3, response_page_id);
EXPECT_EQ(ASCIIToUTF16("MyForm"), response_data.name);
- EXPECT_EQ(GURL("https://myform.com/form.html"), response_data.origin);
+ EXPECT_EQ(GURL("https://myform.com/form.html"), response_data.url);
EXPECT_EQ(GURL("https://myform.com/submit.html"), response_data.action);
ASSERT_EQ(11U, response_data.fields.size());
@@ -2839,7 +2890,7 @@ TEST_F(AutofillManagerTest, FillPhoneNumber) {
// parts. In the other form, rely on the autocomplete type attribute.
FormData form_with_us_number_max_length;
form_with_us_number_max_length.name = ASCIIToUTF16("MyMaxlengthPhoneForm");
- form_with_us_number_max_length.origin =
+ form_with_us_number_max_length.url =
GURL("http://myform.com/phone_form.html");
form_with_us_number_max_length.action =
GURL("http://myform.com/phone_submit.html");
@@ -2968,7 +3019,7 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_ComponentizedNumbers) {
// Verify only the first complete number is filled when there are multiple
// componentized number fields.
FormData form_with_multiple_componentized_phone_fields;
- form_with_multiple_componentized_phone_fields.origin =
+ form_with_multiple_componentized_phone_fields.url =
GURL("http://www.foo.com/");
FormFieldData field;
@@ -3035,7 +3086,7 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_WholeNumbers) {
std::string guid(work_profile->guid());
FormData form_with_multiple_whole_number_fields;
- form_with_multiple_whole_number_fields.origin = GURL("http://www.foo.com/");
+ form_with_multiple_whole_number_fields.url = GURL("http://www.foo.com/");
FormFieldData field;
// Default is zero, have to set to a number autofill can process.
@@ -3089,7 +3140,7 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_FillPartsOnceOnly) {
// Verify only the first complete number is filled when there are multiple
// componentized number fields.
FormData form_with_multiple_componentized_phone_fields;
- form_with_multiple_componentized_phone_fields.origin =
+ form_with_multiple_componentized_phone_fields.url =
GURL("http://www.foo.com/");
FormFieldData field;
@@ -3162,7 +3213,7 @@ TEST_F(AutofillManagerTest,
std::string guid(work_profile->guid());
FormData form_with_misclassified_extension;
- form_with_misclassified_extension.origin = GURL("http://www.foo.com/");
+ form_with_misclassified_extension.url = GURL("http://www.foo.com/");
FormFieldData field;
// Default is zero, have to set to a number autofill can process.
@@ -3223,7 +3274,7 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_BestEfforFilling) {
std::string guid(work_profile->guid());
FormData form_with_no_complete_number;
- form_with_no_complete_number.origin = GURL("http://www.foo.com/");
+ form_with_no_complete_number.url = GURL("http://www.foo.com/");
FormFieldData field;
// Default is zero, have to set to a number autofill can process.
@@ -3281,7 +3332,7 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_FocusOnSecondPhoneNumber) {
std::string guid(work_profile->guid());
FormData form_with_multiple_whole_number_fields;
- form_with_multiple_whole_number_fields.origin = GURL("http://www.foo.com/");
+ form_with_multiple_whole_number_fields.url = GURL("http://www.foo.com/");
FormFieldData field;
// Default is zero, have to set to a number autofill can process.
@@ -3336,7 +3387,7 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_HiddenFieldShouldNotCount) {
std::string guid(work_profile->guid());
FormData form_with_multiple_whole_number_fields;
- form_with_multiple_whole_number_fields.origin = GURL("http://www.foo.com/");
+ form_with_multiple_whole_number_fields.url = GURL("http://www.foo.com/");
FormFieldData field;
// Default is zero, have to set to a number autofill can process.
@@ -3386,7 +3437,7 @@ TEST_F(AutofillManagerTest, FillFirstPhoneNumber_HiddenFieldShouldNotCount) {
TEST_F(AutofillManagerTest, FormWithHiddenOrPresentationalSelects) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
@@ -3462,7 +3513,7 @@ TEST_F(AutofillManagerTest,
std::string guid(work_profile->guid());
FormData form_with_multiple_sections;
- form_with_multiple_sections.origin = GURL("http://www.foo.com/");
+ form_with_multiple_sections.url = GURL("http://www.foo.com/");
FormFieldData field;
// Default is zero, have to set to a number autofill can process.
@@ -3607,7 +3658,7 @@ TEST_F(AutofillManagerTest, FormChangesAddField) {
TEST_F(AutofillManagerTest, FormChangesVisibilityOfFields) {
// Set up our form data.
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
@@ -3973,7 +4024,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictions) {
// Similarly, a second form.
FormData form2;
form2.name = ASCIIToUTF16("MyForm");
- form2.origin = GURL("http://myform.com/form.html");
+ form2.url = GURL("http://myform.com/form.html");
form2.action = GURL("http://myform.com/submit.html");
FormFieldData field;
@@ -4047,7 +4098,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictionsFromApi) {
// First form on the page.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField(/*label=*/"City", /*name=*/"city",
@@ -4070,7 +4121,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictionsFromApi) {
// Second form on the page.
FormData form2;
form2.name = ASCIIToUTF16("MyForm2");
- form2.origin = GURL("http://myform.com/form.html");
+ form2.url = GURL("http://myform.com/form.html");
form2.action = GURL("http://myform.com/submit.html");
test::CreateTestFormField("Last Name", "lastname", "", "text", &field);
form2.fields.push_back(field);
@@ -4184,7 +4235,7 @@ TEST_F(AutofillManagerTest, OnLoadedServerPredictions_ResetManager) {
TEST_F(AutofillManagerTest, DetermineHeuristicsWithOverallPrediction) {
// Set up our form data.
FormData form;
- form.origin = GURL("https://www.myform.com");
+ form.url = GURL("https://www.myform.com");
FormFieldData field;
test::CreateTestFormField("First Name", "firstname", "", "text", &field);
form.fields.push_back(field);
@@ -4578,7 +4629,7 @@ TEST_P(ProfileMatchingTypesTest, DeterminePossibleFieldTypesForUpload) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
@@ -4626,7 +4677,7 @@ INSTANTIATE_TEST_SUITE_P(
TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesForUpload_IsTriggered) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
std::vector<ServerFieldTypeSet> expected_types;
@@ -4728,7 +4779,7 @@ TEST_F(AutofillManagerTest, DeterminePossibleFieldTypesWithMultipleValidities) {
for (const std::vector<TestFieldData>& test_fields : test_cases) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Create the form fields specified in the test case.
@@ -4917,7 +4968,7 @@ TEST_F(AutofillManagerTest, DisambiguateUploadTypes) {
for (const std::vector<TestFieldData>& test_fields : test_cases) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
// Create the form fields specified in the test case.
@@ -4999,7 +5050,7 @@ TEST_F(AutofillManagerTest, OnTextFieldDidChangeAndUnfocus_Upload) {
// Set up our form data (it's already filled out with user data).
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
std::vector<ServerFieldTypeSet> expected_types;
@@ -5049,7 +5100,7 @@ TEST_F(AutofillManagerTest, OnTextFieldDidChangeAndNavigation_Upload) {
// Set up our form data (it's already filled out with user data).
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
std::vector<ServerFieldTypeSet> expected_types;
@@ -5099,7 +5150,7 @@ TEST_F(AutofillManagerTest, OnDidFillAutofillFormDataAndUnfocus_Upload) {
// Set up our form data (empty).
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
std::vector<ServerFieldTypeSet> expected_types;
@@ -5148,7 +5199,7 @@ TEST_F(AutofillManagerTest, GetCreditCardSuggestions_UnrecognizedAttribute) {
// Set up the form data.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
@@ -5186,7 +5237,7 @@ TEST_F(AutofillManagerTest,
// Set up our form data with credit card number split across fields.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData name_field;
@@ -5245,7 +5296,7 @@ TEST_F(AutofillManagerTest, DontSaveCvcInAutocompleteHistory) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
struct {
@@ -5617,9 +5668,9 @@ TEST_F(AutofillManagerTest,
// Set up our form data.
FormData form;
CreateTestCreditCardFormData(&form, false, false);
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
- autofill_client_.set_form_origin(form.origin);
+ autofill_client_.set_form_origin(form.url);
std::vector<FormData> forms(1, form);
FormsSeen(forms);
@@ -5648,7 +5699,7 @@ TEST_F(AutofillManagerTest,
// Set up our form data.
FormData form;
CreateTestCreditCardFormData(&form, false, false);
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
std::vector<FormData> forms(1, form);
FormsSeen(forms);
@@ -5738,7 +5789,7 @@ TEST_F(AutofillManagerTest, ShouldUploadForm) {
// scenarios.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
// Empty Form.
@@ -5856,7 +5907,7 @@ TEST_F(AutofillManagerTest,
// Set up an address form.
FormData mixed_form;
mixed_form.name = ASCIIToUTF16("MyForm");
- mixed_form.origin = GURL("https://myform.com/form.html");
+ mixed_form.url = GURL("https://myform.com/form.html");
mixed_form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First name", "firstname", "", "text", &field);
@@ -5894,7 +5945,7 @@ TEST_F(AutofillManagerTest,
// Set up an address form.
FormData mixed_form;
mixed_form.name = ASCIIToUTF16("MyForm");
- mixed_form.origin = GURL("https://myform.com/form.html");
+ mixed_form.url = GURL("https://myform.com/form.html");
mixed_form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("First name", "firstname", "", "text", &field);
@@ -5932,7 +5983,7 @@ TEST_F(AutofillManagerTest,
// Set up a credit card form.
FormData mixed_form;
mixed_form.name = ASCIIToUTF16("MyForm");
- mixed_form.origin = GURL("https://myform.com/form.html");
+ mixed_form.url = GURL("https://myform.com/form.html");
mixed_form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("Name on Card", "nameoncard", "", "text", &field);
@@ -5962,7 +6013,7 @@ TEST_F(AutofillManagerTest, DisplaySuggestionsForUpdatedServerTypedForm) {
// Create a form with unknown heuristic fields.
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
@@ -6021,7 +6072,7 @@ TEST_F(AutofillManagerTest, DisplaySuggestionsForUpdatedServerTypedForm) {
TEST_F(AutofillManagerTest, FormWithLongOptionValuesIsAcceptable) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
@@ -6067,7 +6118,7 @@ TEST_F(AutofillManagerTest, SmallForm_Upload_NoHeuristicsOrQuery) {
// Set up the form.
FormData form;
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
FormFieldData field;
test::CreateTestFormField("Unknown", "unknown", "", "text", &field);
@@ -6242,6 +6293,270 @@ TEST_F(AutofillManagerTest, DidShowSuggestions_LogAutofillAddressShownMetric) {
HasSubstr("Autofill.FormEvents.CreditCard"))));
}
+TEST_F(AutofillManagerTest, DidShowSuggestions_LogByType_AddressOnly) {
+ // Create a form with name and address fields.
+ FormData form;
+ form.name = ASCIIToUTF16("MyForm");
+ form.button_titles = {std::make_pair(
+ ASCIIToUTF16("Submit"), ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE)};
+ form.url = GURL("http://myform.com/form.html");
+ form.action = GURL("http://myform.com/submit.html");
+ form.main_frame_origin =
+ url::Origin::Create(GURL("https://myform_root.com/form.html"));
+ form.submission_event = SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
+
+ FormFieldData field;
+ test::CreateTestFormField("First Name", "firstname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Last Name", "lastname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Address Line 1", "addr1", "", "text", &field);
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram_tester;
+ autofill_manager_->DidShowSuggestions(/*has_autofill_suggestions=*/true, form,
+ form.fields[0]);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address.AddressOnly",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address.AddressOnly",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+
+ // Logging is not done for other types of address forms.
+ const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
+ EXPECT_THAT(histograms,
+ Not(AnyOf("Autofill.FormEvents.Address.AddressPlusContact",
+ "Autofill.FormEvents.Address.AddressPlusEmail",
+ "Autofill.FormEvents.Address.AddressPlusEmailPlusPhone",
+ "Autofill.FormEvents.Address.AddressPlusPhone",
+ "Autofill.FormEvents.Address.ContactOnly",
+ "Autofill.FormEvents.Address.Other")));
+}
+
+TEST_F(AutofillManagerTest, DidShowSuggestions_LogByType_ContactOnly) {
+ // Create a form with name and contact fields.
+ FormData form;
+ form.name = ASCIIToUTF16("MyForm");
+ form.button_titles = {std::make_pair(
+ ASCIIToUTF16("Submit"), ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE)};
+ form.url = GURL("http://myform.com/form.html");
+ form.action = GURL("http://myform.com/submit.html");
+ form.main_frame_origin =
+ url::Origin::Create(GURL("https://myform_root.com/form.html"));
+ form.submission_event = SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
+
+ FormFieldData field;
+ test::CreateTestFormField("First Name", "firstname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Last Name", "lastname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Email", "email", "", "email", &field);
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram_tester;
+ autofill_manager_->DidShowSuggestions(/*has_autofill_suggestions=*/true, form,
+ form.fields[0]);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address.ContactOnly",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address.ContactOnly",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+
+ // Logging is not done for other types of address forms.
+ const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
+ EXPECT_THAT(histograms,
+ Not(AnyOf("Autofill.FormEvents.Address.AddressPlusContact",
+ "Autofill.FormEvents.Address.AddressPlusEmail",
+ "Autofill.FormEvents.Address.AddressPlusEmailPlusPhone",
+ "Autofill.FormEvents.Address.AddressPlusPhone",
+ "Autofill.FormEvents.Address.AddressOnly",
+ "Autofill.FormEvents.Address.Other")));
+}
+
+TEST_F(AutofillManagerTest, DidShowSuggestions_LogByType_Other) {
+ // Create a form with name fields.
+ FormData form;
+ form.name = ASCIIToUTF16("MyForm");
+ form.button_titles = {std::make_pair(
+ ASCIIToUTF16("Submit"), ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE)};
+ form.url = GURL("http://myform.com/form.html");
+ form.action = GURL("http://myform.com/submit.html");
+ form.main_frame_origin =
+ url::Origin::Create(GURL("https://myform_root.com/form.html"));
+ form.submission_event = SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
+
+ FormFieldData field;
+ test::CreateTestFormField("First Name", "firstname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Middle Name", "middlename", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Last Name", "lastname", "", "text", &field);
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram_tester;
+ autofill_manager_->DidShowSuggestions(/*has_autofill_suggestions=*/true, form,
+ form.fields[0]);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address.Other",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address.Other",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+
+ // Logging is not done for other types of address forms.
+ const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
+ EXPECT_THAT(histograms,
+ Not(AnyOf("Autofill.FormEvents.Address.AddressPlusContact",
+ "Autofill.FormEvents.Address.AddressPlusEmail",
+ "Autofill.FormEvents.Address.AddressPlusEmailPlusPhone",
+ "Autofill.FormEvents.Address.AddressPlusPhone",
+ "Autofill.FormEvents.Address.AddressOnly",
+ "Autofill.FormEvents.Address.ContactOnly")));
+}
+
+TEST_F(AutofillManagerTest, DidShowSuggestions_LogByType_AddressPlusEmail) {
+ // Create a form with name fields.
+ FormData form;
+ form.name = ASCIIToUTF16("MyForm");
+ form.button_titles = {std::make_pair(
+ ASCIIToUTF16("Submit"), ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE)};
+ form.url = GURL("http://myform.com/form.html");
+ form.action = GURL("http://myform.com/submit.html");
+ form.main_frame_origin =
+ url::Origin::Create(GURL("https://myform_root.com/form.html"));
+ form.submission_event = SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
+
+ FormFieldData field;
+ test::CreateTestFormField("First Name", "firstname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Last Name", "lastname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Address Line 1", "addr1", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Email", "email", "", "email", &field);
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram_tester;
+ autofill_manager_->DidShowSuggestions(/*has_autofill_suggestions=*/true, form,
+ form.fields[0]);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusEmail",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusEmail",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusContact",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusContact",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+
+ // Logging is not done for other types of address forms.
+ const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
+ EXPECT_THAT(histograms,
+ Not(AnyOf("Autofill.FormEvents.Address.AddressPlusEmailPlusPhone",
+ "Autofill.FormEvents.Address.AddressPlusPhone",
+ "Autofill.FormEvents.Address.AddressOnly",
+ "Autofill.FormEvents.Address.ContactOnly",
+ "Autofill.FormEvents.Address.Other")));
+}
+
+TEST_F(AutofillManagerTest, DidShowSuggestions_LogByType_AddressPlusPhone) {
+ // Create a form with name fields.
+ FormData form;
+ form.name = ASCIIToUTF16("MyForm");
+ form.button_titles = {std::make_pair(
+ ASCIIToUTF16("Submit"), ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE)};
+ form.url = GURL("http://myform.com/form.html");
+ form.action = GURL("http://myform.com/submit.html");
+ form.main_frame_origin =
+ url::Origin::Create(GURL("https://myform_root.com/form.html"));
+ form.submission_event = SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
+
+ FormFieldData field;
+ test::CreateTestFormField("First Name", "firstname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Last Name", "lastname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Address Line 1", "addr1", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Phone Number", "phonenumber", "", "tel", &field);
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram_tester;
+ autofill_manager_->DidShowSuggestions(/*has_autofill_suggestions=*/true, form,
+ form.fields[0]);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusPhone",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusPhone",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusContact",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusContact",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+
+ // Logging is not done for other types of address forms.
+ const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
+ EXPECT_THAT(histograms,
+ Not(AnyOf("Autofill.FormEvents.Address.AddressPlusEmailPlusPhone",
+ "Autofill.FormEvents.Address.AddressPlusEmail",
+ "Autofill.FormEvents.Address.AddressOnly",
+ "Autofill.FormEvents.Address.ContactOnly",
+ "Autofill.FormEvents.Address.Other")));
+}
+
+TEST_F(AutofillManagerTest,
+ DidShowSuggestions_LogByType_AddressPlusEmailPlusPhone) {
+ // Create a form with name fields.
+ FormData form;
+ form.name = ASCIIToUTF16("MyForm");
+ form.button_titles = {std::make_pair(
+ ASCIIToUTF16("Submit"), ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE)};
+ form.url = GURL("http://myform.com/form.html");
+ form.action = GURL("http://myform.com/submit.html");
+ form.main_frame_origin =
+ url::Origin::Create(GURL("https://myform_root.com/form.html"));
+ form.submission_event = SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
+
+ FormFieldData field;
+ test::CreateTestFormField("First Name", "firstname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Last Name", "lastname", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Address Line 1", "addr1", "", "text", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Phone Number", "phonenumber", "", "tel", &field);
+ form.fields.push_back(field);
+ test::CreateTestFormField("Email", "email", "", "email", &field);
+ form.fields.push_back(field);
+
+ base::HistogramTester histogram_tester;
+ autofill_manager_->DidShowSuggestions(/*has_autofill_suggestions=*/true, form,
+ form.fields[0]);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusEmailPlusPhone",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusEmailPlusPhone",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusContact",
+ FORM_EVENT_SUGGESTIONS_SHOWN, 1);
+ histogram_tester.ExpectBucketCount(
+ "Autofill.FormEvents.Address.AddressPlusContact",
+ FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1);
+
+ // Logging is not done for other types of address forms.
+ const std::string histograms = histogram_tester.GetAllHistogramsRecorded();
+ EXPECT_THAT(histograms,
+ Not(AnyOf("Autofill.FormEvents.Address.AddressPlusPhone",
+ "Autofill.FormEvents.Address.AddressPlusEmail",
+ "Autofill.FormEvents.Address.AddressOnly",
+ "Autofill.FormEvents.Address.ContactOnly",
+ "Autofill.FormEvents.Address.Other")));
+}
+
TEST_F(AutofillManagerTest,
DidShowSuggestions_LogAutofillCreditCardShownMetric) {
FormData form;
@@ -6392,7 +6707,7 @@ class OnFocusOnFormFieldTest : public AutofillManagerTest,
TEST_P(OnFocusOnFormFieldTest, AddressSuggestions) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
// Set a valid autocomplete attribute for the first name.
@@ -6423,7 +6738,7 @@ TEST_P(OnFocusOnFormFieldTest, AddressSuggestions_AutocompleteOffNotRespected) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
// Set a valid autocomplete attribute for the first name.
@@ -6451,7 +6766,7 @@ TEST_P(OnFocusOnFormFieldTest, AddressSuggestions_AutocompleteOffRespected) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("https://myform.com/form.html");
+ form.url = GURL("https://myform.com/form.html");
form.action = GURL("https://myform.com/submit.html");
FormFieldData field;
// Set a valid autocomplete attribute for the first name.
diff --git a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
index bd1bbb316a7..86ac1dcbbf1 100644
--- a/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -229,7 +229,7 @@ void AutofillMergeTest::MergeProfiles(const std::string& profiles,
// Create a test form.
FormData form;
form.name = base::ASCIIToUTF16("MyTestForm");
- form.origin = GURL("https://www.example.com/origin.html");
+ form.url = GURL("https://www.example.com/origin.html");
form.action = GURL("https://www.example.com/action.html");
// Parse the input line by line.
diff --git a/chromium/components/autofill/core/browser/autofill_metadata.cc b/chromium/components/autofill/core/browser/autofill_metadata.cc
index 99527207f77..cb2686f98f5 100644
--- a/chromium/components/autofill/core/browser/autofill_metadata.cc
+++ b/chromium/components/autofill/core/browser/autofill_metadata.cc
@@ -4,6 +4,9 @@
#include "components/autofill/core/browser/autofill_metadata.h"
+#include "components/autofill/core/common/autofill_clock.h"
+#include "components/autofill/core/common/autofill_constants.h"
+
namespace autofill {
bool AutofillMetadata::operator==(const AutofillMetadata& metadata) const {
@@ -17,6 +20,10 @@ bool AutofillMetadata::operator!=(const AutofillMetadata& metadata) const {
return !(*this == metadata);
}
+bool AutofillMetadata::IsDeletable() const {
+ return IsAutofillEntryWithUseDateDeletable(use_date);
+}
+
std::ostream& operator<<(std::ostream& os, const AutofillMetadata& metadata) {
return os << metadata.id << " " << metadata.use_count << " "
<< metadata.use_date << " " << metadata.has_converted << " "
diff --git a/chromium/components/autofill/core/browser/autofill_metadata.h b/chromium/components/autofill/core/browser/autofill_metadata.h
index 3fbc2e12a26..e8b62f16704 100644
--- a/chromium/components/autofill/core/browser/autofill_metadata.h
+++ b/chromium/components/autofill/core/browser/autofill_metadata.h
@@ -21,6 +21,10 @@ struct AutofillMetadata {
bool operator==(const AutofillMetadata&) const;
bool operator!=(const AutofillMetadata&) const;
+ // Returns whether the metadata is deletable: if it has not been used for
+ // longer than |kDisusedAddressDeletionTimeDelta|.
+ bool IsDeletable() const;
+
// The ID for the model. This should be the guid for local data and server_id
// for the server data.
std::string id;
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.cc b/chromium/components/autofill/core/browser/autofill_metrics.cc
index b88ad9a0269..3afc5c867ca 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics.cc
@@ -684,6 +684,12 @@ void AutofillMetrics::LogCreditCardInfoBarMetric(
metric, NUM_INFO_BAR_METRICS);
}
+ if (options.from_dynamic_change_form) {
+ base::UmaHistogramEnumeration(
+ "Autofill.CreditCardInfoBar" + destination + ".FromDynamicChangeForm",
+ metric, NUM_INFO_BAR_METRICS);
+ }
+
if (options.has_non_focusable_field) {
base::UmaHistogramEnumeration(
"Autofill.CreditCardInfoBar" + destination + ".FromNonFocusableForm",
@@ -746,6 +752,11 @@ void AutofillMetrics::LogSaveCardPromptMetric(
metric_with_destination_and_show + ".FromNonFocusableForm", metric,
NUM_SAVE_CARD_PROMPT_METRICS);
}
+ if (options.from_dynamic_change_form) {
+ base::UmaHistogramEnumeration(
+ metric_with_destination_and_show + ".FromDynamicChangeForm", metric,
+ NUM_SAVE_CARD_PROMPT_METRICS);
+ }
base::UmaHistogramEnumeration(
metric_with_destination_and_show +
PreviousSaveCreditCardPromptUserDecisionToString(
@@ -1450,6 +1461,11 @@ void AutofillMetrics::LogAutofillSuggestionAcceptedIndex(int index) {
}
// static
+void AutofillMetrics::LogAutofillFormCleared() {
+ base::RecordAction(base::UserMetricsAction("Autofill_ClearedForm"));
+}
+
+// static
void AutofillMetrics::LogNumberOfEditedAutofilledFields(
size_t num_edited_autofilled_fields,
bool observed_submission) {
@@ -1871,6 +1887,17 @@ void AutofillMetrics::LogWalletSyncTransportCardsOptIn(bool is_opted_in) {
"Autofill.HadUserOptedIn_To_WalletSyncTransportServerCards", is_opted_in);
}
+void AutofillMetrics::LogCardUploadEnabledMetric(
+ CardUploadEnabledMetric metric_value,
+ AutofillSyncSigninState sync_state) {
+ const std::string parent_metric = std::string("Autofill.CardUploadEnabled");
+ base::UmaHistogramEnumeration(parent_metric, metric_value);
+
+ const std::string child_metric =
+ parent_metric + GetMetricsSyncStateSuffix(sync_state);
+ base::UmaHistogramEnumeration(child_metric, metric_value);
+}
+
// static
const char* AutofillMetrics::GetMetricsSyncStateSuffix(
AutofillSyncSigninState sync_state) {
@@ -1881,8 +1908,10 @@ const char* AutofillMetrics::GetMetricsSyncStateSuffix(
return ".SignedIn";
case AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled:
return ".SignedInAndWalletSyncTransportEnabled";
- case AutofillSyncSigninState::kSignedInAndSyncFeature:
- return ".SignedInAndSyncFeature";
+ case AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled:
+ return ".SignedInAndSyncFeatureEnabled";
+ case AutofillSyncSigninState::kSyncPaused:
+ return ".SyncPaused";
case AutofillSyncSigninState::kNumSyncStates:
return ".Unknown";
}
diff --git a/chromium/components/autofill/core/browser/autofill_metrics.h b/chromium/components/autofill/core/browser/autofill_metrics.h
index 39c231415ae..3688ad1beff 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics.h
+++ b/chromium/components/autofill/core/browser/autofill_metrics.h
@@ -116,6 +116,9 @@ class AutofillMetrics {
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,
+ // All the required conditions were satisfied even though the form is
+ // dynamic changed.
+ UPLOAD_OFFERED_FROM_DYNAMIC_CHANGE_FORM = 1 << 17,
// Update |kNumCardUploadDecisionMetrics| when adding new enum here.
};
@@ -746,7 +749,7 @@ class AutofillMetrics {
NUM_WALLET_REQUIRED_ACTIONS
};
- // For mesuring how wallet addresses are converted to local profiles.
+ // For measuring how wallet addresses are converted to local profiles.
enum WalletAddressConversionType : int {
// The converted wallet address was merged into an existing local profile.
CONVERTED_ADDRESS_MERGED,
@@ -755,9 +758,27 @@ class AutofillMetrics {
NUM_CONVERTED_ADDRESS_CONVERSION_TYPES
};
- // To record whether or not the upload event was sent,
+ // To record whether the upload event was sent.
enum class UploadEventStatus { kNotSent, kSent, kMaxValue = kSent };
+ // Log all the scenarios that contribute to the decision of whether card
+ // upload is enabled or not.
+ enum class CardUploadEnabledMetric {
+ SYNC_SERVICE_NULL = 0,
+ SYNC_SERVICE_PERSISTENT_AUTH_ERROR = 1,
+ SYNC_SERVICE_MISSING_AUTOFILL_WALLET_DATA_ACTIVE_TYPE = 2,
+ SYNC_SERVICE_MISSING_AUTOFILL_PROFILE_ACTIVE_TYPE = 3,
+ ACCOUNT_WALLET_STORAGE_UPLOAD_DISABLED = 4,
+ USING_SECONDARY_SYNC_PASSPHRASE = 5,
+ LOCAL_SYNC_ENABLED = 6,
+ PAYMENTS_INTEGRATION_DISABLED = 7,
+ EMAIL_EMPTY = 8,
+ EMAIL_DOMAIN_NOT_SUPPORTED = 9,
+ AUTOFILL_UPSTREAM_DISABLED = 10,
+ CARD_UPLOAD_ENABLED = 11,
+ kMaxValue = CARD_UPLOAD_ENABLED,
+ };
+
// Utility to log URL keyed form interaction events.
class FormInteractionsUkmLogger {
public:
@@ -1109,6 +1130,9 @@ class AutofillMetrics {
// Log the index of the selected Autofill suggestion in the popup.
static void LogAutofillSuggestionAcceptedIndex(int index);
+ // Logs that the user cleared the form.
+ static void LogAutofillFormCleared();
+
// Log the number of days since an Autocomplete suggestion was last used.
static void LogAutocompleteDaysSinceLastUse(size_t days);
@@ -1231,13 +1255,18 @@ class AutofillMetrics {
// server cards to be shown.
static void LogWalletSyncTransportCardsOptIn(bool is_opted_in);
+ // Records the reason for why (or why not) card upload was enabled for the
+ // user.
+ static void LogCardUploadEnabledMetric(CardUploadEnabledMetric metric,
+ AutofillSyncSigninState sync_state);
+
static const char* GetMetricsSyncStateSuffix(
AutofillSyncSigninState sync_state);
private:
static void Log(AutocompleteEvent event);
- static const int kNumCardUploadDecisionMetrics = 17;
+ static const int kNumCardUploadDecisionMetrics = 18;
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 87afa30900e..8a6bdb8ab63 100644
--- a/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -27,6 +27,7 @@
#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_credit_card_save_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/popup_item_ids.h"
@@ -34,7 +35,6 @@
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/browser/test_autofill_manager.h"
-#include "components/autofill/core/browser/test_credit_card_save_manager.h"
#include "components/autofill/core/browser/test_form_data_importer.h"
#include "components/autofill/core/browser/test_form_structure.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
@@ -84,8 +84,8 @@ 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>>>;
+using ExpectedUkmMetricsRecord = std::vector<std::pair<const char*, int64_t>>;
+using ExpectedUkmMetrics = std::vector<ExpectedUkmMetricsRecord>;
const char* kTestGuid = "00000000-0000-0000-0000-000000000001";
@@ -309,9 +309,9 @@ void AutofillMetricsTest::SetUp() {
std::make_unique<MockAutocompleteHistoryManager>();
payments::TestPaymentsClient* payments_client =
- new payments::TestPaymentsClient(
- autofill_driver_->GetURLLoaderFactory(), autofill_client_.GetPrefs(),
- autofill_client_.GetIdentityManager(), personal_data_.get());
+ new payments::TestPaymentsClient(autofill_driver_->GetURLLoaderFactory(),
+ autofill_client_.GetIdentityManager(),
+ personal_data_.get());
autofill_client_.set_test_payments_client(
std::unique_ptr<payments::TestPaymentsClient>(payments_client));
TestCreditCardSaveManager* credit_card_save_manager =
@@ -501,7 +501,7 @@ TEST_F(AutofillMetricsTest, QualityMetrics) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -688,7 +688,7 @@ TEST_F(AutofillMetricsTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
std::vector<ServerFieldType> heuristic_types, server_types;
@@ -768,7 +768,7 @@ TEST_F(AutofillMetricsTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
std::vector<ServerFieldType> heuristic_types, server_types;
@@ -835,7 +835,7 @@ TEST_F(AutofillMetricsTest, LogHiddenRepresentationalFieldSkipDecision) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -977,7 +977,7 @@ TEST_F(AutofillMetricsTest, LogRepeatedAddressTypeRationalized) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -1084,7 +1084,7 @@ TEST_F(AutofillMetricsTest, LogRepeatedStateCountryTypeRationalized) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -1221,7 +1221,7 @@ TEST_F(AutofillMetricsTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
std::vector<ServerFieldType> heuristic_types, server_types;
@@ -1287,7 +1287,7 @@ TEST_F(AutofillMetricsTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
std::vector<ServerFieldType> heuristic_types, server_types;
@@ -1588,7 +1588,7 @@ TEST_P(QualityMetricsTest, Classification) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -1763,7 +1763,7 @@ TEST_F(AutofillMetricsTest, TimingMetrics) {
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -1804,7 +1804,7 @@ TEST_F(AutofillMetricsTest, QualityMetrics_NoSubmission) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -1990,7 +1990,7 @@ TEST_F(AutofillMetricsTest, QualityMetrics_NoSubmission) {
TEST_F(AutofillMetricsTest, QualityMetrics_BasedOnAutocomplete) {
FormData form;
form.name = ASCIIToUTF16("MyForm");
- form.origin = GURL("http://myform.com/form.html");
+ form.url = GURL("http://myform.com/form.html");
form.action = GURL("http://myform.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -2105,7 +2105,7 @@ TEST_F(AutofillMetricsTest, UpiVirtualPaymentAddress) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -2164,7 +2164,7 @@ TEST_F(AutofillMetricsTest, PredictedMetricsWithAutocomplete) {
FormData form;
FormFieldData field;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -2241,7 +2241,7 @@ TEST_F(AutofillMetricsTest, SaneMetricsWithCacheMismatch) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -2340,7 +2340,7 @@ TEST_F(AutofillMetricsTest, StoredProfileCountAutofillableFormSubmission) {
// Construct a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -2376,7 +2376,7 @@ TEST_F(AutofillMetricsTest, StoredProfileCountNonAutofillableFormSubmission) {
// Construct a non-fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -2408,7 +2408,7 @@ TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields) {
// Construct a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -2462,7 +2462,7 @@ TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields_NoSubmission) {
// Construct a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -2511,7 +2511,7 @@ TEST_F(AutofillMetricsTest, DeveloperEngagement) {
// Start with a non-fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -2615,7 +2615,7 @@ TEST_F(AutofillMetricsTest,
// Start with a non-fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -2661,7 +2661,7 @@ TEST_F(AutofillMetricsTest,
UkmDeveloperEngagement_LogFillableFormParsedWithTypeHints) {
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -2718,7 +2718,7 @@ TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogUpiVpaTypeHint) {
{});
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -2919,7 +2919,7 @@ TEST_F(AutofillMetricsTest, AddressSuggestionsCount) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -2991,7 +2991,7 @@ TEST_P(AutofillMetricsCompanyTest, CompanyNameSuggestions) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3035,7 +3035,7 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3095,6 +3095,48 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
user_action_tester.GetActionCount("Autofill_SelectedSuggestion"));
}
+ // Simulate showing a credit card suggestion polled from "Credit card number"
+ // field along with a "Clear form" footer suggestion.
+ {
+ base::UserActionTester user_action_tester;
+ autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
+ form.fields[1]);
+ EXPECT_EQ(1, user_action_tester.GetActionCount(
+ "Autofill_ShowedCreditCardSuggestions"));
+ }
+
+ // Simulate selecting a "Clear form" suggestion.
+ {
+ base::UserActionTester user_action_tester;
+ std::string guid("10000000-0000-0000-0000-000000000001"); // local card
+ external_delegate_->OnQuery(0, form, form.fields.front(), gfx::RectF());
+ external_delegate_->DidAcceptSuggestion(base::string16(),
+ POPUP_ITEM_ID_CLEAR_FORM, 0);
+ EXPECT_EQ(1, user_action_tester.GetActionCount("Autofill_ClearedForm"));
+ }
+
+ // Simulate showing a credit card suggestion polled from "Credit card number"
+ // field, this time to submit the form.
+ {
+ base::UserActionTester user_action_tester;
+ autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
+ form.fields[1]);
+ EXPECT_EQ(1, user_action_tester.GetActionCount(
+ "Autofill_ShowedCreditCardSuggestions"));
+ }
+
+ // Simulate selecting a credit card suggestions.
+ {
+ base::UserActionTester user_action_tester;
+ std::string guid("10000000-0000-0000-0000-000000000001"); // local card
+ external_delegate_->OnQuery(0, form, form.fields.front(), gfx::RectF());
+ external_delegate_->DidAcceptSuggestion(
+ ASCIIToUTF16("Test"),
+ autofill_manager_->MakeFrontendID(guid, std::string()), 0);
+ EXPECT_EQ(1,
+ user_action_tester.GetActionCount("Autofill_SelectedSuggestion"));
+ }
+
// Simulate filling a credit card suggestion.
{
base::UserActionTester user_action_tester;
@@ -3119,43 +3161,53 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
"Autofill_FormSubmitted_NonFillable"));
}
- VerifyUkm(
- test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
- {{{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NAME_FULL},
- {UkmTextFieldDidChangeType::kHtmlFieldTypeName, HTML_TYPE_UNSPECIFIED},
- {UkmTextFieldDidChangeType::kServerTypeName, CREDIT_CARD_NAME_FULL},
- {UkmSuggestionsShownType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[0]))},
- {UkmSuggestionsShownType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}},
- {{UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
- {UkmTextFieldDidChangeType::kHtmlFieldTypeName, HTML_TYPE_UNSPECIFIED},
- {UkmTextFieldDidChangeType::kServerTypeName, CREDIT_CARD_NUMBER},
- {UkmSuggestionsShownType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields[1]))},
- {UkmSuggestionsShownType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
- // Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
- // call to |external_delegate_->DidAcceptSuggestion|. Second, from call to
- // |autofill_manager_->FillOrPreviewForm|.
- VerifyUkm(
- test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
- {{{UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, true},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.front()))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}},
- {{UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
- {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
- {UkmSuggestionFilledType::kIsForCreditCardName, true},
- {UkmSuggestionFilledType::kFieldSignatureName,
- Collapse(CalculateFieldSignatureForField(form.fields.front()))},
- {UkmSuggestionFilledType::kFormSignatureName,
- Collapse(CalculateFormSignature(form))}}});
+ // Expect one record for a click on the cardholder name field and one record
+ // for each of the 3 clicks on the card number field.
+ ExpectedUkmMetricsRecord name_field_record{
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NAME_FULL},
+ {UkmTextFieldDidChangeType::kHtmlFieldTypeName, HTML_TYPE_UNSPECIFIED},
+ {UkmTextFieldDidChangeType::kServerTypeName, CREDIT_CARD_NAME_FULL},
+ {UkmSuggestionsShownType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[0]))},
+ {UkmSuggestionsShownType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}};
+ ExpectedUkmMetricsRecord number_field_record{
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmTextFieldDidChangeType::kHeuristicTypeName, CREDIT_CARD_NUMBER},
+ {UkmTextFieldDidChangeType::kHtmlFieldTypeName, HTML_TYPE_UNSPECIFIED},
+ {UkmTextFieldDidChangeType::kServerTypeName, CREDIT_CARD_NUMBER},
+ {UkmSuggestionsShownType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields[1]))},
+ {UkmSuggestionsShownType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}};
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionsShownType::kEntryName,
+ {name_field_record, number_field_record, number_field_record,
+ number_field_record});
+
+ // Expect 3 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from
+ // call to |external_delegate_->DidAcceptSuggestion|. Second and third, from
+ // ExpectedUkmMetrics |autofill_manager_->FillOrPreviewForm|.
+ ExpectedUkmMetricsRecord from_did_accept_suggestion{
+ {UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, true},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.front()))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}};
+ ExpectedUkmMetricsRecord from_fill_or_preview_form{
+ {UkmSuggestionFilledType::kRecordTypeName, CreditCard::LOCAL_CARD},
+ {UkmSuggestionFilledType::kMillisecondsSinceFormParsedName, 0},
+ {UkmSuggestionFilledType::kIsForCreditCardName, true},
+ {UkmSuggestionFilledType::kFieldSignatureName,
+ Collapse(CalculateFieldSignatureForField(form.fields.front()))},
+ {UkmSuggestionFilledType::kFormSignatureName,
+ Collapse(CalculateFormSignature(form))}};
+ VerifyUkm(test_ukm_recorder_, form, UkmSuggestionFilledType::kEntryName,
+ {from_did_accept_suggestion, from_fill_or_preview_form,
+ from_fill_or_preview_form});
+
// Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState|
// because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|.
VerifySubmitFormUkm(test_ukm_recorder_, form,
@@ -3168,7 +3220,7 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) {
TEST_F(AutofillMetricsTest, UpiVpaUkmTest) {
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
FormFieldData field;
@@ -3199,7 +3251,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3338,7 +3390,7 @@ TEST_F(AutofillMetricsTest, PolledCreditCardSuggestions_DebounceLogs) {
// Set up the form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
std::vector<ServerFieldType> field_types;
@@ -3398,7 +3450,7 @@ TEST_F(AutofillMetricsTest, QueriedCreditCardFormIsSecure) {
// Set up the form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3416,7 +3468,7 @@ TEST_F(AutofillMetricsTest, QueriedCreditCardFormIsSecure) {
{
// Simulate having seen this insecure form on page load.
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(autofill_client_.form_origin());
@@ -3435,7 +3487,7 @@ TEST_F(AutofillMetricsTest, QueriedCreditCardFormIsSecure) {
{
// Simulate having seen this secure form on page load.
autofill_manager_->Reset();
- form.origin = GURL("https://example.com/form.html");
+ form.url = GURL("https://example.com/form.html");
form.action = GURL("https://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(autofill_client_.form_origin());
@@ -3459,7 +3511,7 @@ TEST_F(AutofillMetricsTest, PolledProfileSuggestions_DebounceLogs) {
// Set up the form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3516,7 +3568,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardParsedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3548,7 +3600,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardInteractedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3604,7 +3656,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardPopupSuppressedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3662,7 +3714,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardShownFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3867,7 +3919,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSelectedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -3948,7 +4000,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardFilledFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -4189,7 +4241,7 @@ TEST_F(AutofillMetricsTest, CreditCardGetRealPanDuration) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -4260,7 +4312,7 @@ TEST_F(AutofillMetricsTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -4302,7 +4354,7 @@ TEST_P(AutofillMetricsIFrameTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
FormFieldData field;
@@ -4348,7 +4400,7 @@ TEST_P(AutofillMetricsIFrameTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
FormFieldData field;
@@ -4395,7 +4447,7 @@ TEST_P(AutofillMetricsIFrameTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -4443,7 +4495,7 @@ TEST_P(AutofillMetricsIFrameTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -4491,7 +4543,7 @@ TEST_P(AutofillMetricsIFrameTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -4555,7 +4607,7 @@ TEST_F(AutofillMetricsTest, ShouldNotLogFormEventNoCardForAddressForm) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -4596,7 +4648,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardSubmittedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5097,7 +5149,7 @@ TEST_P(AutofillMetricsIFrameTest, CreditCardWillSubmitFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5419,7 +5471,7 @@ TEST_F(AutofillMetricsTest, MixedParsedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5462,7 +5514,7 @@ TEST_F(AutofillMetricsTest, AddressParsedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5504,7 +5556,7 @@ TEST_F(AutofillMetricsTest, AddressInteractedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5580,7 +5632,7 @@ TEST_F(AutofillMetricsTest, AddressSuppressedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5673,7 +5725,7 @@ TEST_F(AutofillMetricsTest, AddressShownFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5799,7 +5851,7 @@ TEST_F(AutofillMetricsTest, AddressFilledFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -5918,7 +5970,7 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -6132,7 +6184,7 @@ TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -6320,7 +6372,7 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -6431,7 +6483,7 @@ TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -6519,7 +6571,7 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) {
// Start with a form with insufficiently many fields.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -6821,7 +6873,7 @@ TEST_F(
AutofillFormSubmittedState_DoNotCountUnfilledFieldsWithOnlyFillWhenFocused) {
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -6952,7 +7004,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_EmptyForm) {
// Load a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -6978,7 +7030,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_CreditCardForm) {
// Load a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("https://example.com/form.html");
+ form.url = GURL("https://example.com/form.html");
form.action = GURL("https://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -7147,7 +7199,7 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction_AddressForm) {
// Load a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -7395,7 +7447,7 @@ TEST_F(AutofillMetricsTest, FormFillDuration) {
// Load a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -7800,7 +7852,7 @@ TEST_F(AutofillMetricsTest, ProfileActionOnFormSubmitted) {
// Load a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -7925,7 +7977,7 @@ class AutofillMetricsParseQueryResponseTest : public testing::Test {
public:
void SetUp() override {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
form.main_frame_origin = url::Origin::Create(GURL("http://foo_root.com"));
FormFieldData field;
field.form_control_type = "text";
@@ -8049,7 +8101,7 @@ TEST_F(AutofillMetricsTest, NonsecureCreditCardForm) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
GURL frame_origin("http://example_root.com/form.html");
form.main_frame_origin = url::Origin::Create(frame_origin);
@@ -8107,7 +8159,7 @@ TEST_F(AutofillMetricsTest,
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("https://example.com/form.html");
+ form.url = GURL("https://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin =
url::Origin::Create(GURL("http://example_root.com/form.html"));
@@ -8234,7 +8286,7 @@ TEST_F(AutofillMetricsTest, MAYBE_AutofillSuggestionShownTest) {
false /* include_full_server_credit_card */);
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example_cc.com/form.html");
+ form.url = GURL("http://example_cc.com/form.html");
form.action = GURL("http://example_cc.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -8267,14 +8319,13 @@ TEST_F(AutofillMetricsTest, MAYBE_AutofillSuggestionShownTest) {
}
TEST_F(AutofillMetricsTest, DynamicFormMetrics) {
- scoped_feature_list_.InitWithFeatures(
- {features::kAutofillDynamicForms},
- {features::kAutofillRestrictUnownedFieldsToFormlessCheckout});
+ scoped_feature_list_.InitAndDisableFeature(
+ features::kAutofillRestrictUnownedFieldsToFormlessCheckout);
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
FormFieldData field;
std::vector<ServerFieldType> field_types;
@@ -8396,7 +8447,7 @@ TEST_F(AutofillMetricsTest, LogUserHappinessBySecurityLevel_FromFormEvents) {
// Load a fillable form.
FormData form;
form.name = ASCIIToUTF16("TestForm");
- form.origin = GURL("http://example.com/form.html");
+ form.url = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
@@ -8639,9 +8690,10 @@ TEST_F(AutofillMetricsTest, LogSaveCardPromptMetric_BySyncState) {
/*is_reshow=*/true, AutofillClient::SaveCreditCardOptions(),
/*previous_save_credit_card_prompt_user_decision=*/0,
security_state::SecurityLevel::SECURE,
- SyncSigninState::kSignedInAndSyncFeature);
+ SyncSigninState::kSignedInAndSyncFeatureEnabled);
histogram_tester.ExpectBucketCount(
- "Autofill.SaveCreditCardPrompt.Local.Reshows.SignedInAndSyncFeature",
+ "Autofill.SaveCreditCardPrompt.Local.Reshows."
+ "SignedInAndSyncFeatureEnabled",
AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, 1);
}
}
diff --git a/chromium/components/autofill/core/browser/autofill_profile.cc b/chromium/components/autofill/core/browser/autofill_profile.cc
index dd8c59b8f7a..2260617f9a6 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile.cc
@@ -12,11 +12,11 @@
#include <set>
#include "base/guid.h"
+#include "base/hash/sha1.h"
#include "base/i18n/case_conversion.h"
#include "base/i18n/char_iterator.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
-#include "base/sha1.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -228,6 +228,7 @@ ServerFieldType NormalizeTypeForValidityCheck(ServerFieldType type) {
AutofillProfile::AutofillProfile(const std::string& guid,
const std::string& origin)
: AutofillDataModel(guid, origin),
+ company_(this),
phone_number_(this),
record_type_(LOCAL_PROFILE),
has_converted_(false),
@@ -235,6 +236,7 @@ AutofillProfile::AutofillProfile(const std::string& guid,
AutofillProfile::AutofillProfile(RecordType type, const std::string& server_id)
: AutofillDataModel(base::GenerateGUID(), std::string()),
+ company_(this),
phone_number_(this),
server_id_(server_id),
record_type_(type),
@@ -245,6 +247,7 @@ AutofillProfile::AutofillProfile(RecordType type, const std::string& server_id)
AutofillProfile::AutofillProfile()
: AutofillDataModel(base::GenerateGUID(), std::string()),
+ company_(this),
phone_number_(this),
record_type_(LOCAL_PROFILE),
has_converted_(false),
@@ -252,6 +255,7 @@ AutofillProfile::AutofillProfile()
AutofillProfile::AutofillProfile(const AutofillProfile& profile)
: AutofillDataModel(std::string(), std::string()),
+ company_(this),
phone_number_(this),
weak_ptr_factory_(this) {
operator=(profile);
@@ -277,6 +281,7 @@ AutofillProfile& AutofillProfile::operator=(const AutofillProfile& profile) {
name_ = profile.name_;
email_ = profile.email_;
company_ = profile.company_;
+ company_.set_profile(this);
phone_number_ = profile.phone_number_;
phone_number_.set_profile(this);
@@ -444,12 +449,6 @@ int AutofillProfile::Compare(const AutofillProfile& profile) const {
return 0;
}
-bool AutofillProfile::EqualsSansOrigin(const AutofillProfile& profile) const {
- return guid() == profile.guid() &&
- language_code() == profile.language_code() &&
- Compare(profile) == 0;
-}
-
bool AutofillProfile::EqualsForSyncPurposes(const AutofillProfile& profile)
const {
return use_count() == profile.use_count() &&
@@ -565,7 +564,7 @@ bool AutofillProfile::MergeDataFrom(const AutofillProfile& profile,
NameInfo name;
EmailInfo email;
- CompanyInfo company;
+ CompanyInfo company(this);
PhoneNumber phone_number(this);
Address address;
@@ -665,16 +664,6 @@ bool AutofillProfile::SaveAdditionalInfo(const AutofillProfile& profile,
}
// static
-bool AutofillProfile::SupportsMultiValue(ServerFieldType type) {
- FieldTypeGroup group = AutofillType(type).group();
- return group == NAME ||
- group == NAME_BILLING ||
- group == EMAIL ||
- group == PHONE_HOME ||
- group == PHONE_BILLING;
-}
-
-// static
void AutofillProfile::CreateDifferentiatingLabels(
const std::vector<AutofillProfile*>& profiles,
const std::string& app_locale,
@@ -832,12 +821,24 @@ bool AutofillProfile::HasGreaterFrescocencyThan(
base::Time comparison_time,
bool use_client_validation,
bool use_server_validation) const {
+ double score = GetFrecencyScore(comparison_time);
+ double other_score = other->GetFrecencyScore(comparison_time);
+
+ const double kEpsilon = 0.001;
+ if (std::fabs(score - other_score) > kEpsilon)
+ return score > other_score;
+
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) {
+ if (use_date() != other->use_date())
+ return use_date() > other->use_date();
+ return guid() > other->guid();
+ }
+
if (is_valid && !other_is_valid)
return true;
return false;
diff --git a/chromium/components/autofill/core/browser/autofill_profile.h b/chromium/components/autofill/core/browser/autofill_profile.h
index bf1c5494762..17126388e74 100644
--- a/chromium/components/autofill/core/browser/autofill_profile.h
+++ b/chromium/components/autofill/core/browser/autofill_profile.h
@@ -100,9 +100,6 @@ class AutofillProfile : public AutofillDataModel {
// themselves.
int Compare(const AutofillProfile& profile) const;
- // Same as operator==, but ignores differences in origin.
- bool EqualsSansOrigin(const AutofillProfile& profile) const;
-
// Same as operator==, but ignores differences in guid and cares about
// differences in usage stats.
bool EqualsForSyncPurposes(const AutofillProfile& profile) const;
@@ -149,9 +146,6 @@ class AutofillProfile : public AutofillDataModel {
bool SaveAdditionalInfo(const AutofillProfile& profile,
const std::string& app_locale);
- // Returns |true| if |type| accepts multi-values.
- static bool SupportsMultiValue(ServerFieldType type);
-
// Creates a differentiating label for each of the |profiles|.
// Labels consist of the minimal differentiating combination of:
// 1. Full name.
@@ -208,9 +202,8 @@ class AutofillProfile : public AutofillDataModel {
// 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.
+ // puts all the valid profiles before the invalid ones in case of frecency
+ // tie. Please see AutofillDataModel::HasGreaterFrecencyThan.
bool HasGreaterFrescocencyThan(const AutofillProfile* other,
base::Time comparison_time,
bool use_client_validation,
diff --git a/chromium/components/autofill/core/browser/autofill_profile_comparator_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_comparator_unittest.cc
index 36da4fdf765..0fac04009e1 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_comparator_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_comparator_unittest.cc
@@ -6,11 +6,13 @@
#include "base/guid.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/contact_info.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "testing/gtest/include/gtest/gtest.h"
// Field Type Constants
@@ -758,9 +760,16 @@ TEST_F(AutofillProfileComparatorTest, MergeEmailAddresses) {
}
TEST_F(AutofillProfileComparatorTest, MergeCompanyNames) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{autofill::features::
+ kAutofillRejectCompanyBirthyear},
+ /*disabled_features=*/{});
+
static const char kCompanyA[] = "Some Company";
static const char kCompanyB[] = "SÔMÈ ÇÖMPÁÑÝ";
static const char kCompanyC[] = "SÔMÈ ÇÖMPÁÑÝ A.G.";
+ static const char kCompanyD[] = "1987";
CompanyInfo company_a;
company_a.SetRawInfo(COMPANY_NAME, UTF8ToUTF16(kCompanyA));
@@ -781,15 +790,31 @@ TEST_F(AutofillProfileComparatorTest, MergeCompanyNames) {
AutofillProfile profile_c = CreateProfileWithCompanyName(kCompanyC);
profile_c.set_use_date(profile_a.use_date() - base::TimeDelta::FromDays(1));
+ // Company Name D is in the format of a birthyear, invalid and non-verified.
+ CompanyInfo company_d;
+ company_d.SetRawInfo(COMPANY_NAME, UTF8ToUTF16(kCompanyD));
+ AutofillProfile profile_d = CreateProfileWithCompanyName(kCompanyD);
+ profile_a.set_use_date(base::Time::Now());
+
MergeCompanyNamesAndExpect(profile_a, profile_a, company_a);
MergeCompanyNamesAndExpect(profile_a, profile_b, company_b);
MergeCompanyNamesAndExpect(profile_a, profile_c, company_c);
+ MergeCompanyNamesAndExpect(profile_a, profile_d, company_a);
+
MergeCompanyNamesAndExpect(profile_b, profile_a, company_b);
MergeCompanyNamesAndExpect(profile_b, profile_b, company_b);
MergeCompanyNamesAndExpect(profile_b, profile_c, company_c);
+ MergeCompanyNamesAndExpect(profile_b, profile_d, company_b);
+
MergeCompanyNamesAndExpect(profile_c, profile_a, company_c);
MergeCompanyNamesAndExpect(profile_c, profile_b, company_c);
MergeCompanyNamesAndExpect(profile_c, profile_c, company_c);
+ MergeCompanyNamesAndExpect(profile_c, profile_d, company_c);
+
+ MergeCompanyNamesAndExpect(profile_d, profile_a, company_a);
+ MergeCompanyNamesAndExpect(profile_d, profile_b, company_b);
+ MergeCompanyNamesAndExpect(profile_d, profile_c, company_c);
+ MergeCompanyNamesAndExpect(profile_d, profile_d, company_d);
}
TEST_F(AutofillProfileComparatorTest, MergePhoneNumbers_NA) {
diff --git a/chromium/components/autofill/core/browser/autofill_profile_unittest.cc b/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
index 539a255e776..46f955119e1 100644
--- a/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
+++ b/chromium/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -1943,7 +1943,7 @@ TEST_P(HasGreaterFrescocencyTest, HasGreaterFrescocency) {
test_case.server_validity_state_b,
AutofillDataModel::SERVER);
- base::Time now = base::Time::Now();
+ const base::Time now = base::Time::Now();
if (test_case.expectation == EQUAL) {
EXPECT_EQ(profile_a.HasGreaterFrecencyThan(&profile_b, now),
@@ -1963,6 +1963,36 @@ TEST_P(HasGreaterFrescocencyTest, HasGreaterFrescocency) {
test_case.use_server_validation));
}
+// Validity is only checked in case of tie in frecency. Frecency has greater
+// priority than validity in frescocency.
+TEST_P(HasGreaterFrescocencyTest, PriorityCheck) {
+ AutofillProfile profile_invalid("00000000-0000-0000-0000-000000000001", "");
+ AutofillProfile profile_valid("00000000-0000-0000-0000-000000000002", "");
+
+ profile_invalid.SetValidityState(EMAIL_ADDRESS, AutofillDataModel::INVALID,
+ AutofillDataModel::CLIENT);
+ profile_valid.SetValidityState(ADDRESS_HOME_ZIP, AutofillDataModel::INVALID,
+ AutofillDataModel::SERVER);
+
+ profile_valid.SetValidityState(ADDRESS_HOME_CITY, AutofillDataModel::VALID,
+ AutofillDataModel::CLIENT);
+ profile_valid.SetValidityState(PHONE_HOME_NUMBER, AutofillDataModel::VALID,
+ AutofillDataModel::SERVER);
+
+ profile_invalid.set_use_count(100);
+ profile_valid.set_use_count(10);
+
+ const base::Time now = base::Time::Now();
+ const base::Time past = now - base::TimeDelta::FromDays(1);
+
+ profile_invalid.set_use_date(now);
+ profile_valid.set_use_date(past);
+
+ EXPECT_TRUE(profile_invalid.HasGreaterFrecencyThan(&profile_valid, now));
+ EXPECT_TRUE(profile_invalid.HasGreaterFrescocencyThan(&profile_valid, now,
+ true, true));
+}
+
INSTANTIATE_TEST_SUITE_P(
AutofillProfileTest,
HasGreaterFrescocencyTest,
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.cc b/chromium/components/autofill/core/browser/autofill_test_utils.cc
index ffab385a580..9c3e280433b 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.cc
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.cc
@@ -115,7 +115,7 @@ void CreateTestAddressFormData(FormData* form,
ASCIIToUTF16("MyForm") + ASCIIToUTF16(unique_id ? unique_id : "");
form->button_titles = {std::make_pair(
ASCIIToUTF16("Submit"), ButtonTitleType::BUTTON_ELEMENT_SUBMIT_TYPE)};
- form->origin = GURL("http://myform.com/form.html");
+ form->url = GURL("http://myform.com/form.html");
form->action = GURL("http://myform.com/submit.html");
form->main_frame_origin =
url::Origin::Create(GURL("https://myform_root.com/form.html"));
@@ -185,7 +185,7 @@ void CreateTestPersonalInformationFormData(FormData* form,
const char* unique_id) {
form->name =
ASCIIToUTF16("MyForm") + ASCIIToUTF16(unique_id ? unique_id : "");
- form->origin = GURL("http://myform.com/form.html");
+ form->url = GURL("http://myform.com/form.html");
form->action = GURL("http://myform.com/submit.html");
form->main_frame_origin =
url::Origin::Create(GURL("https://myform_root.com/form.html"));
@@ -210,12 +210,12 @@ void CreateTestCreditCardFormData(FormData* form,
form->name =
ASCIIToUTF16("MyForm") + ASCIIToUTF16(unique_id ? unique_id : "");
if (is_https) {
- form->origin = GURL("https://myform.com/form.html");
+ form->url = GURL("https://myform.com/form.html");
form->action = GURL("https://myform.com/submit.html");
form->main_frame_origin =
url::Origin::Create(GURL("https://myform_root.com/form.html"));
} else {
- form->origin = GURL("http://myform.com/form.html");
+ form->url = GURL("http://myform.com/form.html");
form->action = GURL("http://myform.com/submit.html");
form->main_frame_origin =
url::Origin::Create(GURL("http://myform_root.com/form.html"));
@@ -337,12 +337,6 @@ AutofillProfile GetVerifiedProfile() {
return profile;
}
-AutofillProfile GetVerifiedProfile2() {
- AutofillProfile profile(GetFullProfile2());
- profile.set_origin(kSettingsOrigin);
- return profile;
-}
-
AutofillProfile GetServerProfile() {
AutofillProfile profile(AutofillProfile::SERVER_PROFILE, "id1");
// Note: server profiles don't have email addresses and only have full names.
diff --git a/chromium/components/autofill/core/browser/autofill_test_utils.h b/chromium/components/autofill/core/browser/autofill_test_utils.h
index 02eb5847a07..9b74aabc9b7 100644
--- a/chromium/components/autofill/core/browser/autofill_test_utils.h
+++ b/chromium/components/autofill/core/browser/autofill_test_utils.h
@@ -112,9 +112,6 @@ AutofillProfile GetIncompleteProfile2();
// Returns a verified profile full of dummy info.
AutofillProfile GetVerifiedProfile();
-// Returns a verified profile full of dummy info, different to the above.
-AutofillProfile GetVerifiedProfile2();
-
// Returns a server profile full of dummy info.
AutofillProfile GetServerProfile();
@@ -127,12 +124,6 @@ CreditCard GetCreditCard();
// Returns a credit card full of dummy info, different to the above.
CreditCard GetCreditCard2();
-// Returns a verified credit card full of dummy info.
-CreditCard GetVerifiedCreditCard();
-
-// Returns a verified credit card full of dummy info, different to the above.
-CreditCard GetVerifiedCreditCard2();
-
// Returns a masked server card full of dummy info.
CreditCard GetMaskedServerCard();
CreditCard GetMaskedServerCardAmex();
diff --git a/chromium/components/autofill/core/browser/autofill_type.cc b/chromium/components/autofill/core/browser/autofill_type.cc
index 62bb3c04655..e873833612a 100644
--- a/chromium/components/autofill/core/browser/autofill_type.cc
+++ b/chromium/components/autofill/core/browser/autofill_type.cc
@@ -777,10 +777,10 @@ std::string AutofillType::ServerFieldTypeToString(ServerFieldType type) {
return "SEARCH_TERM";
case PRICE:
return "PRICE";
-
+ case NOT_PASSWORD:
+ return "NOT_PASSWORD";
case AMBIGUOUS_TYPE:
return "AMBIGUOUS_TYPE";
-
case MAX_VALID_FIELD_TYPE:
return std::string();
}
diff --git a/chromium/components/autofill/core/browser/contact_form_label_formatter.cc b/chromium/components/autofill/core/browser/contact_form_label_formatter.cc
index 47701675865..48feb02b774 100644
--- a/chromium/components/autofill/core/browser/contact_form_label_formatter.cc
+++ b/chromium/components/autofill/core/browser/contact_form_label_formatter.cc
@@ -4,33 +4,54 @@
#include "components/autofill/core/browser/contact_form_label_formatter.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/label_formatter_utils.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);
- }
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types)
+ : LabelFormatter(app_locale, focused_field_type, groups, field_types) {}
+
+ContactFormLabelFormatter::~ContactFormLabelFormatter() {}
+
+// Note that the order--name, phone, and email--in which parts of the label
+// are possibly added ensures that the label is formatted correctly for
+// |focused_group| and for this kind of formatter.
+base::string16 ContactFormLabelFormatter::GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const {
+ std::vector<base::string16> label_parts;
+ if (focused_group != NAME) {
+ AddLabelPartIfNotEmpty(GetLabelName(profile, app_locale()), &label_parts);
+ }
+
+ if (focused_group != PHONE_HOME) {
+ AddLabelPartIfNotEmpty(MaybeGetPhone(profile), &label_parts);
}
- const FieldTypeGroup group =
- AutofillType(AutofillType(focused_field_type).GetStorableType()).group();
- filtered_field_type_groups_.erase(group);
+
+ if (focused_group != EMAIL) {
+ AddLabelPartIfNotEmpty(MaybeGetEmail(profile), &label_parts);
+ }
+
+ return ConstructLabelLine(label_parts);
}
-ContactFormLabelFormatter::~ContactFormLabelFormatter() {}
+base::string16 ContactFormLabelFormatter::MaybeGetEmail(
+ const AutofillProfile& profile) const {
+ return data_util::ContainsEmail(groups())
+ ? GetLabelEmail(profile, app_locale())
+ : base::string16();
+}
-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;
+base::string16 ContactFormLabelFormatter::MaybeGetPhone(
+ const AutofillProfile& profile) const {
+ return data_util::ContainsPhone(groups())
+ ? GetLabelPhone(profile, app_locale())
+ : base::string16();
}
} // 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
index 38684976af4..be4eb1cab56 100644
--- a/chromium/components/autofill/core/browser/contact_form_label_formatter.h
+++ b/chromium/components/autofill/core/browser/contact_form_label_formatter.h
@@ -5,7 +5,6 @@
#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>
@@ -22,26 +21,23 @@ 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);
+ uint32_t groups,
+ const std::vector<ServerFieldType>& field_types);
~ContactFormLabelFormatter() override;
- std::vector<base::string16> GetLabels(
- const std::vector<AutofillProfile*>& profiles) const override;
+ base::string16 GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) 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_;
+ // Returns |profile|'s email address if |profile| has a valid email address
+ // and if this formatter's associated form has an email field.
+ base::string16 MaybeGetEmail(const AutofillProfile& profile) const;
- // 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_;
+ // Returns |profile|'s phone number if |profile| has a phone number and if
+ // this formatter's associated form has a phone field.
+ base::string16 MaybeGetPhone(const AutofillProfile& profile) const;
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/contact_form_label_formatter_unittest.cc b/chromium/components/autofill/core/browser/contact_form_label_formatter_unittest.cc
new file mode 100644
index 00000000000..d9f18e37bfc
--- /dev/null
+++ b/chromium/components/autofill/core/browser/contact_form_label_formatter_unittest.cc
@@ -0,0 +1,306 @@
+// 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"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/guid.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::ElementsAre;
+
+namespace autofill {
+namespace {
+
+std::vector<ServerFieldType> GetNamePhoneAndEmailFieldTypes() {
+ return {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER, EMAIL_ADDRESS};
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsWithMissingProfiles) {
+ const std::vector<AutofillProfile*> profiles{};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_FIRST, GetNamePhoneAndEmailFieldTypes(), profiles);
+ EXPECT_TRUE(formatter->GetLabels(profiles).empty());
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "jackie@outlook.com",
+ "", "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "", "", "19 N Square",
+ "", "Boston", "MA", "02113", "US", "+1 (617) 523-2338");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "John", "", "Adams", "", "",
+ "141 Franklin St.", "", "Quincy", "MA", "02169", "US",
+ "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_LAST, GetNamePhoneAndEmailFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("(617) 730-2000"),
+ base::ASCIIToUTF16("jfk@gmail.com")}),
+ base::ASCIIToUTF16("jackie@outlook.com"),
+ base::ASCIIToUTF16("(617) 523-2338"), base::string16()));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedEmail) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "jackie@outlook.com",
+ "", "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "", "", "19 N Square",
+ "", "Boston", "MA", "02113", "US", "+1 (617) 523-2338");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "141 Franklin St.", "",
+ "Quincy", "MA", "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", EMAIL_ADDRESS, GetNamePhoneAndEmailFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("(617) 730-2000")}),
+ base::ASCIIToUTF16("Jackie Kennedy"),
+ ConstructLabelLine({base::ASCIIToUTF16("Paul Revere"),
+ base::ASCIIToUTF16("(617) 523-2338")}),
+ base::string16()));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForUSProfilesAndFocusedPhone) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Jackie", "", "Kennedy", "jackie@outlook.com",
+ "", "151 Irving Ave", "", "Hyannis", "MA", "02601", "US",
+ "");
+
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Paul", "", "Revere", "", "", "19 N Square",
+ "", "Boston", "MA", "02113", "US", "+1 (617) 523-2338");
+
+ AutofillProfile profile4 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile4, "", "", "", "", "", "141 Franklin St.", "",
+ "Quincy", "MA", "02169", "US", "");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2, &profile3,
+ &profile4};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("en-US", PHONE_HOME_WHOLE_NUMBER,
+ GetNamePhoneAndEmailFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("John F Kennedy"),
+ base::ASCIIToUTF16("jfk@gmail.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Jackie Kennedy"),
+ base::ASCIIToUTF16("jackie@outlook.com")}),
+ base::ASCIIToUTF16("Paul Revere"), base::string16()));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForBRProfilesAndFocusedName) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", NAME_LAST, GetNamePhoneAndEmailFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("(11) 2648-0254"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("(21) 98765-0000"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForBRProfilesAndFocusedEmail) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "pt-BR", EMAIL_ADDRESS, GetNamePhoneAndEmailFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::ASCIIToUTF16("(11) 2648-0254")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"),
+ base::ASCIIToUTF16("(21) 98765-0000")})));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForBRProfilesAndFocusedPhone) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Tarsila", "do", "Amaral", "tarsila@aol.com",
+ "", "Av. Pedro Álvares Cabral, 1301", "", "Vila Mariana",
+ "São Paulo", "SP", "04094-050", "BR",
+ "+55 11 2648-0254");
+
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Artur", "", "Avila", "aavila@uol.com.br", "",
+ "Estr. Dona Castorina, 110", "", "Jardim Botânico",
+ "Rio de Janeiro", "RJ", "22460-320", "BR",
+ "21987650000");
+
+ const std::vector<AutofillProfile*> profiles{&profile1, &profile2};
+ const std::unique_ptr<LabelFormatter> formatter =
+ LabelFormatter::Create("pt-BR", PHONE_HOME_WHOLE_NUMBER,
+ GetNamePhoneAndEmailFieldTypes(), profiles);
+
+ EXPECT_THAT(
+ formatter->GetLabels(profiles),
+ ElementsAre(
+ ConstructLabelLine({base::ASCIIToUTF16("Tarsila do Amaral"),
+ base::ASCIIToUTF16("tarsila@aol.com")}),
+ ConstructLabelLine({base::ASCIIToUTF16("Artur Avila"),
+ base::ASCIIToUTF16("aavila@uol.com.br")})));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForNameAndPhoneWithFocusedName) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_LAST, {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER},
+ profiles);
+
+ // Checks that the email address is excluded when the form does not contain an
+ // email field.
+ EXPECT_THAT(formatter->GetLabels(profiles),
+ ElementsAre(base::ASCIIToUTF16("(617) 730-2000")));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForNameAndPhoneWithFocusedPhone) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", PHONE_HOME_WHOLE_NUMBER,
+ {NAME_FIRST, NAME_LAST, PHONE_HOME_WHOLE_NUMBER}, profiles);
+
+ // Checks that the email address is excluded when the form does not contain an
+ // email field.
+ EXPECT_THAT(formatter->GetLabels(profiles),
+ ElementsAre(base::ASCIIToUTF16("John F Kennedy")));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForNameAndEmailWithFocusedName) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", NAME_LAST, {NAME_FIRST, NAME_LAST, EMAIL_ADDRESS}, profiles);
+
+ // Checks that the phone number is excluded when the form does not contain a
+ // phone field.
+ EXPECT_THAT(formatter->GetLabels(profiles),
+ ElementsAre(base::ASCIIToUTF16("jfk@gmail.com")));
+}
+
+TEST(ContactFormLabelFormatterTest, GetLabelsForNameAndEmailWithFocusedEmail) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "John", "F", "Kennedy", "jfk@gmail.com", "",
+ "333 Washington St", "", "Brookline", "MA", "02445",
+ "US", "16177302000");
+
+ const std::vector<AutofillProfile*> profiles{&profile};
+ const std::unique_ptr<LabelFormatter> formatter = LabelFormatter::Create(
+ "en-US", EMAIL_ADDRESS, {NAME_FIRST, NAME_LAST, EMAIL_ADDRESS}, profiles);
+
+ // Checks that the phone number is excluded when the form does not contain a
+ // phone field.
+ EXPECT_THAT(formatter->GetLabels(profiles),
+ ElementsAre(base::ASCIIToUTF16("John F Kennedy")));
+}
+
+} // namespace
+} // namespace autofill \ No newline at end of file
diff --git a/chromium/components/autofill/core/browser/contact_info.cc b/chromium/components/autofill/core/browser/contact_info.cc
index c2d5104c2eb..3f8dc709edc 100644
--- a/chromium/components/autofill/core/browser/contact_info.cc
+++ b/chromium/components/autofill/core/browser/contact_info.cc
@@ -13,9 +13,11 @@
#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"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_l10n_util.h"
+#include "components/autofill/core/common/autofill_regexes.h"
namespace autofill {
@@ -218,6 +220,8 @@ void EmailInfo::SetRawInfo(ServerFieldType type, const base::string16& value) {
CompanyInfo::CompanyInfo() {}
+CompanyInfo::CompanyInfo(const AutofillProfile* profile) : profile_(profile) {}
+
CompanyInfo::CompanyInfo(const CompanyInfo& info) {
*this = info;
}
@@ -228,12 +232,13 @@ CompanyInfo& CompanyInfo::operator=(const CompanyInfo& info) {
if (this == &info)
return *this;
- company_name_ = info.company_name_;
+ company_name_ = info.GetRawInfo(COMPANY_NAME);
return *this;
}
bool CompanyInfo::operator==(const CompanyInfo& other) const {
- return this == &other || company_name_ == other.company_name_;
+ return this == &other ||
+ GetRawInfo(COMPANY_NAME) == other.GetRawInfo(COMPANY_NAME);
}
void CompanyInfo::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
@@ -241,7 +246,7 @@ void CompanyInfo::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
}
base::string16 CompanyInfo::GetRawInfo(ServerFieldType type) const {
- return company_name_;
+ return IsValidOrVerified(company_name_) ? company_name_ : base::string16();
}
void CompanyInfo::SetRawInfo(ServerFieldType type,
@@ -250,4 +255,16 @@ void CompanyInfo::SetRawInfo(ServerFieldType type,
company_name_ = value;
}
+bool CompanyInfo::IsValidOrVerified(const base::string16& value) const {
+ if (!base::FeatureList::IsEnabled(
+ autofill::features::kAutofillRejectCompanyBirthyear))
+ return true;
+
+ if (profile_ && profile_->IsVerified())
+ return true;
+
+ // Companies that are of the format of a four digit birth year are not valid.
+ return !MatchesPattern(value, base::UTF8ToUTF16("^(19|20)\\d{2}$"));
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/contact_info.h b/chromium/components/autofill/core/browser/contact_info.h
index 3c5e451a73c..3bb79c4121c 100644
--- a/chromium/components/autofill/core/browser/contact_info.h
+++ b/chromium/components/autofill/core/browser/contact_info.h
@@ -13,6 +13,8 @@
namespace autofill {
+class AutofillProfile;
+
// A form group that stores name information.
class NameInfo : public FormGroup {
public:
@@ -91,6 +93,7 @@ class CompanyInfo : public FormGroup {
public:
CompanyInfo();
CompanyInfo(const CompanyInfo& info);
+ explicit CompanyInfo(const AutofillProfile* profile);
~CompanyInfo() override;
CompanyInfo& operator=(const CompanyInfo& info);
@@ -100,12 +103,15 @@ class CompanyInfo : public FormGroup {
// FormGroup:
base::string16 GetRawInfo(ServerFieldType type) const override;
void SetRawInfo(ServerFieldType type, const base::string16& value) override;
+ void set_profile(const AutofillProfile* profile) { profile_ = profile; }
private:
// FormGroup:
void GetSupportedTypes(ServerFieldTypeSet* supported_types) const override;
+ bool IsValidOrVerified(const base::string16& value) const;
base::string16 company_name_;
+ const AutofillProfile* profile_ = nullptr;
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/contact_info_unittest.cc b/chromium/components/autofill/core/browser/contact_info_unittest.cc
index 3f2502fa654..cac7c92e4b6 100644
--- a/chromium/components/autofill/core/browser/contact_info_unittest.cc
+++ b/chromium/components/autofill/core/browser/contact_info_unittest.cc
@@ -11,8 +11,11 @@
#include "base/strings/string_util.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_profile.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/common/autofill_features.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
@@ -397,4 +400,96 @@ INSTANTIATE_TEST_SUITE_P(
NamePartsAreEmptyTestCase{"", "Mitchell", "", "", false},
NamePartsAreEmptyTestCase{"", "", "Morrison", "", false}));
+TEST(CompanyTest, CompanyNameYear) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillRejectCompanyBirthyear},
+ /*disabled_features=*/{});
+
+ AutofillProfile profile;
+ CompanyInfo company(&profile);
+ ASSERT_FALSE(profile.IsVerified());
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("Google"));
+ EXPECT_EQ(UTF8ToUTF16("Google"), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("1987"));
+ EXPECT_EQ(UTF8ToUTF16(""), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("It was 1987."));
+ EXPECT_EQ(UTF8ToUTF16("It was 1987."), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("1987 was the year."));
+ EXPECT_EQ(UTF8ToUTF16("1987 was the year."),
+ company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("Yes, 1987 was the year."));
+ EXPECT_EQ(UTF8ToUTF16("Yes, 1987 was the year."),
+ company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("2019"));
+ EXPECT_EQ(UTF8ToUTF16(""), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("1818"));
+ EXPECT_EQ(UTF8ToUTF16("1818"), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("2345"));
+ EXPECT_EQ(UTF8ToUTF16("2345"), company.GetRawInfo(COMPANY_NAME));
+
+ profile.set_origin("Not empty");
+ ASSERT_TRUE(profile.IsVerified());
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("Google"));
+ EXPECT_EQ(UTF8ToUTF16("Google"), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("1987"));
+ EXPECT_EQ(UTF8ToUTF16("1987"), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("2019"));
+ EXPECT_EQ(UTF8ToUTF16("2019"), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("1818"));
+ EXPECT_EQ(UTF8ToUTF16("1818"), company.GetRawInfo(COMPANY_NAME));
+
+ company.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("2345"));
+ EXPECT_EQ(UTF8ToUTF16("2345"), company.GetRawInfo(COMPANY_NAME));
+}
+
+TEST(CompanyTest, CompanyNameYearCopy) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillRejectCompanyBirthyear},
+ /*disabled_features=*/{});
+
+ AutofillProfile profile;
+ ASSERT_FALSE(profile.IsVerified());
+
+ CompanyInfo company_google(&profile);
+ CompanyInfo company_year(&profile);
+
+ company_google.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("Google"));
+ company_year.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("1987"));
+
+ company_google = company_year;
+ EXPECT_EQ(UTF8ToUTF16(""), company_google.GetRawInfo(COMPANY_NAME));
+}
+
+TEST(CompanyTest, CompanyNameYearIsEqual) {
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitWithFeatures(
+ /*enabled_features=*/{features::kAutofillRejectCompanyBirthyear},
+ /*disabled_features=*/{});
+
+ AutofillProfile profile;
+ ASSERT_FALSE(profile.IsVerified());
+
+ CompanyInfo company_old(&profile);
+ CompanyInfo company_young(&profile);
+
+ company_old.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("2019"));
+ company_young.SetRawInfo(COMPANY_NAME, UTF8ToUTF16("1987"));
+
+ EXPECT_EQ(company_old, company_young);
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/field_types.h b/chromium/components/autofill/core/browser/field_types.h
index c10fd8df61d..022575a16da 100644
--- a/chromium/components/autofill/core/browser/field_types.h
+++ b/chromium/components/autofill/core/browser/field_types.h
@@ -172,9 +172,12 @@ enum ServerFieldType {
// Price fields are detected, but not filled.
PRICE = 98,
+ // Password-type fields which are not actual passwords.
+ NOT_PASSWORD = 99,
+
// No new types can be added without a corresponding change to the Autofill
// server.
- MAX_VALID_FIELD_TYPE = 99,
+ MAX_VALID_FIELD_TYPE = 100,
};
// 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 15e57a10910..93a16220a75 100644
--- a/chromium/components/autofill/core/browser/form_data_importer.cc
+++ b/chromium/components/autofill/core/browser/form_data_importer.cc
@@ -31,6 +31,7 @@
#include "components/autofill/core/browser/phone_number_i18n.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_util.h"
namespace autofill {
@@ -133,6 +134,11 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
ImportedCreditCardRecordType::NO_CARD) {
return;
}
+ // Do not offer upload save for google domain.
+ if (net::HasGoogleHost(submitted_form.main_frame_origin().GetURL()) &&
+ is_credit_card_upstream_enabled) {
+ return;
+ }
// A credit card was successfully imported, but it's possible it is already a
// local or server card. First, check to see if we should offer local card
// migration in this case, as local cards could go either way.
@@ -177,7 +183,8 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::NEW_CARD);
credit_card_save_manager_->AttemptToOfferCardUploadSave(
- submitted_form, has_non_focusable_field_, *imported_credit_card,
+ submitted_form, from_dynamic_change_form_, has_non_focusable_field_,
+ *imported_credit_card,
/*uploading_local_card=*/imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::LOCAL_CARD);
} else {
@@ -185,7 +192,8 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
DCHECK(imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::NEW_CARD);
credit_card_save_manager_->AttemptToOfferCardLocalSave(
- has_non_focusable_field_, *imported_credit_card);
+ from_dynamic_change_form_, has_non_focusable_field_,
+ *imported_credit_card);
}
}
@@ -508,6 +516,8 @@ CreditCard FormDataImporter::ExtractCreditCardFromForm(
if (field_type.group() != CREDIT_CARD)
continue;
+ if (form.value_from_dynamic_change_form())
+ from_dynamic_change_form_ = true;
if (!field->is_focusable)
has_non_focusable_field_ = true;
diff --git a/chromium/components/autofill/core/browser/form_data_importer.h b/chromium/components/autofill/core/browser/form_data_importer.h
index a195d96cc86..9678400c066 100644
--- a/chromium/components/autofill/core/browser/form_data_importer.h
+++ b/chromium/components/autofill/core/browser/form_data_importer.h
@@ -13,9 +13,9 @@
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_client.h"
-#include "components/autofill/core/browser/credit_card_save_manager.h"
#include "components/autofill/core/browser/form_structure.h"
-#include "components/autofill/core/browser/local_card_migration_manager.h"
+#include "components/autofill/core/browser/payments/credit_card_save_manager.h"
+#include "components/autofill/core/browser/payments/local_card_migration_manager.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/personal_data_manager.h"
@@ -120,6 +120,9 @@ class FormDataImporter {
CreditCard ExtractCreditCardFromForm(const FormStructure& form,
bool* hasDuplicateFieldType);
+ // Whether a dynamic change form is imported.
+ bool from_dynamic_change_form_ = false;
+
// Whether the form imported has non-focusable fields after user entered
// information into it.
bool has_non_focusable_field_ = false;
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 00280a55dde..e1d3e18b03a 100644
--- a/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/chromium/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -38,6 +38,7 @@
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -287,7 +288,7 @@ class FormDataImporterTest : public FormDataImporterTestBase,
TEST_F(FormDataImporterTest, ImportAddressProfiles) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -325,7 +326,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles) {
TEST_F(FormDataImporterTest, ImportAddressProfiles_BadEmail) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -355,7 +356,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_BadEmail) {
// Tests that a 'confirm email' field does not block profile import.
TEST_F(FormDataImporterTest, ImportAddressProfiles_TwoEmails) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name:", "name", "George Washington", "text",
@@ -386,7 +387,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_TwoEmails) {
// Tests two email fields containing different values blocks profile import.
TEST_F(FormDataImporterTest, ImportAddressProfiles_TwoDifferentEmails) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name:", "name", "George Washington", "text",
@@ -417,7 +418,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_TwoDifferentEmails) {
// Tests that not enough filled fields will result in not importing an address.
TEST_F(FormDataImporterTest, ImportAddressProfiles_NotEnoughFilledFields) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -441,7 +442,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MinimumAddressUSA) {
// United States addresses must specifiy one address line, a city, state and
// zip code.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name:", "name", "Barack Obama", "text", &field);
@@ -468,7 +469,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MinimumAddressGB) {
// British addresses do not require a state/province as the county is usually
// not requested on forms.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name:", "name", "David Cameron", "text", &field);
@@ -495,7 +496,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MinimumAddressGI) {
// Gibraltar has the most minimal set of requirements for a valid address.
// There are no cities or provinces and no postal/zip code system.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name:", "name", "Sir Adrian Johns", "text",
@@ -516,7 +517,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MinimumAddressGI) {
TEST_F(FormDataImporterTest,
ImportAddressProfiles_PhoneNumberSplitAcrossMultipleFields) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -562,7 +563,7 @@ TEST_F(FormDataImporterTest,
TEST_F(FormDataImporterTest, ImportAddressProfiles_MultilineAddress) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -603,7 +604,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MultilineAddress) {
TEST_F(FormDataImporterTest,
ImportAddressProfiles_TwoValidProfilesDifferentForms) {
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -641,7 +642,7 @@ TEST_F(FormDataImporterTest,
// Now create a completely different profile.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
test::CreateTestFormField("First name:", "first_name", "John", "text",
&field);
@@ -677,7 +678,7 @@ TEST_F(FormDataImporterTest,
TEST_F(FormDataImporterTest, ImportAddressProfiles_TwoValidProfilesSameForm) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -745,7 +746,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_TwoValidProfilesSameForm) {
TEST_F(FormDataImporterTest,
ImportAddressProfiles_OneValidProfileSameForm_PartsHidden) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -814,7 +815,7 @@ TEST_F(FormDataImporterTest,
// A maximum of two address profiles are imported per form.
TEST_F(FormDataImporterTest, ImportAddressProfiles_ThreeValidProfilesSameForm) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -901,7 +902,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_ThreeValidProfilesSameForm) {
TEST_F(FormDataImporterTest, ImportAddressProfiles_SameProfileWithConflict) {
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -944,7 +945,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_SameProfileWithConflict) {
// Now create an updated profile.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
test::CreateTestFormField("First name:", "first_name", "George", "text",
&field);
@@ -992,7 +993,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_SameProfileWithConflict) {
TEST_F(FormDataImporterTest, ImportAddressProfiles_MissingInfoInOld) {
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -1026,7 +1027,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MissingInfoInOld) {
// Submit a form with new data for the first profile.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
test::CreateTestFormField("First name:", "first_name", "George", "text",
&field);
@@ -1066,7 +1067,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MissingInfoInOld) {
TEST_F(FormDataImporterTest, ImportAddressProfiles_MissingInfoInNew) {
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -1107,7 +1108,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MissingInfoInNew) {
// Submit a form with new data for the first profile.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
test::CreateTestFormField("First name:", "first_name", "George", "text",
&field);
@@ -1144,7 +1145,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_MissingInfoInNew) {
TEST_F(FormDataImporterTest, ImportAddressProfiles_InsufficientAddress) {
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -1199,7 +1200,7 @@ TEST_F(FormDataImporterTest,
// Simulate a form submission with conflicting info.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "Marion Mitchell",
@@ -1253,7 +1254,7 @@ TEST_F(FormDataImporterTest,
// Tests that no profile is inferred if the country is not recognized.
TEST_F(FormDataImporterTest, ImportAddressProfiles_UnrecognizedCountry) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -1294,7 +1295,7 @@ TEST_F(FormDataImporterTest, ImportAddressProfiles_UnrecognizedCountry) {
TEST_F(FormDataImporterTest,
ImportAddressProfiles_CompleteComposedCountryName) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -1340,7 +1341,7 @@ TEST_F(FormDataImporterTest,
TEST_F(FormDataImporterTest,
ImportAddressProfiles_IncompleteComposedCountryName) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -1384,7 +1385,7 @@ TEST_F(FormDataImporterTest,
TEST_F(FormDataImporterTest, ImportCreditCard_Valid) {
// Add a single valid credit card form.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111-1111-1111-1111", "01",
"2999");
@@ -1414,7 +1415,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_Valid) {
// Tests that an invalid credit card number is not extracted.
TEST_F(FormDataImporterTest, ImportCreditCard_InvalidCardNumber) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Jim Johansen", "1000000000000000", "02",
"2999");
@@ -1439,7 +1440,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_InvalidCardNumber) {
// Tests that an invalid credit card expiration is not extracted.
TEST_F(FormDataImporterTest, ImportCreditCard_InvalidExpiryDate) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Smalls Biggie", "4111-1111-1111-1111", "0",
"2999");
@@ -1467,7 +1468,7 @@ TEST_F(FormDataImporterTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamEditableExpirationDate);
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Smalls Biggie", "4111-1111-1111-1111", "", "");
@@ -1488,7 +1489,7 @@ TEST_F(FormDataImporterTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamEditableExpirationDate);
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Smalls Biggie", "4111-1111-1111-1111", "01",
"2000");
@@ -1508,7 +1509,7 @@ TEST_F(FormDataImporterTest,
TEST_F(FormDataImporterTest, ImportCreditCard_MonthSelectInvalidText) {
// Add a single valid credit card form with an invalid option value.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111-1111-1111-1111",
"Feb (2)", "2999");
@@ -1551,7 +1552,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_MonthSelectInvalidText) {
TEST_F(FormDataImporterTest, ImportCreditCard_TwoValidCards) {
// Start with a single valid credit card form.
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form1, "Biggie Smalls", "4111-1111-1111-1111", "01",
"2999");
@@ -1575,7 +1576,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_TwoValidCards) {
// Add a second different valid credit card.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form2, "", "5500 0000 0000 0004", "02", "2999");
@@ -1601,7 +1602,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_TwoValidCards) {
// This form has the expiration year as one field with MM/YY.
TEST_F(FormDataImporterTest, ImportCreditCard_Month2DigitYearCombination) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "John MMYY",
@@ -1622,7 +1623,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_Month2DigitYearCombination) {
// This form has the expiration year as one field with MM/YYYY.
TEST_F(FormDataImporterTest, ImportCreditCard_Month4DigitYearCombination) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "John MMYYYY",
@@ -1643,7 +1644,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_Month4DigitYearCombination) {
// This form has the expiration year as one field with M/YYYY.
TEST_F(FormDataImporterTest, ImportCreditCard_1DigitMonth4DigitYear) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "John MYYYY",
@@ -1663,7 +1664,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_1DigitMonth4DigitYear) {
// This form has the expiration year as a 2-digit field.
TEST_F(FormDataImporterTest, ImportCreditCard_2DigitYear) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "John Smith",
@@ -1701,7 +1702,7 @@ TEST_F(FormDataImporterTest,
// Type the same data as the masked card into a form.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "John Dillinger", "4111111111111111", "01",
"2999");
@@ -1733,7 +1734,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_DuplicateServerCards_FullCard) {
// Type the same data as the unmasked card into a form.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Clyde Barrow", "378282246310005", "04", "2999");
@@ -1749,7 +1750,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_DuplicateServerCards_FullCard) {
TEST_F(FormDataImporterTest, ImportCreditCard_SameCreditCardWithConflict) {
// Start with a single valid credit card form.
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form1, "Biggie Smalls", "4111-1111-1111-1111", "01",
"2998");
@@ -1774,7 +1775,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_SameCreditCardWithConflict) {
// Add a second different valid credit card where the year is different but
// the credit card number matches.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form2, "Biggie Smalls", "4111 1111 1111 1111", "01",
/* different year */ "2999");
@@ -1801,7 +1802,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_SameCreditCardWithConflict) {
TEST_F(FormDataImporterTest, ImportCreditCard_ShouldReturnLocalCard) {
// Start with a single valid credit card form.
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form1, "Biggie Smalls", "4111-1111-1111-1111", "01",
"2998");
@@ -1826,7 +1827,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_ShouldReturnLocalCard) {
// Add a second different valid credit card where the year is different but
// the credit card number matches.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form2, "Biggie Smalls", "4111 1111 1111 1111", "01",
/* different year */ "2999");
@@ -1856,7 +1857,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_ShouldReturnLocalCard) {
TEST_F(FormDataImporterTest, ImportCreditCard_EmptyCardWithConflict) {
// Start with a single valid credit card form.
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form1, "Biggie Smalls", "4111-1111-1111-1111", "01",
"2998");
@@ -1881,7 +1882,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_EmptyCardWithConflict) {
// Add a second credit card with no number.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form2, "Biggie Smalls", /* no number */ nullptr, "01",
"2999");
@@ -1910,7 +1911,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_EmptyCardWithConflict) {
TEST_F(FormDataImporterTest, ImportCreditCard_MissingInfoInNew) {
// Start with a single valid credit card form.
FormData form1;
- form1.origin = GURL("https://wwww.foo.com");
+ form1.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form1, "Biggie Smalls", "4111-1111-1111-1111", "01",
"2999");
@@ -1935,7 +1936,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_MissingInfoInNew) {
// Add a second different valid credit card where the name is missing but
// the credit card number matches.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form2, /* missing name */ nullptr,
"4111-1111-1111-1111", "01", "2999");
@@ -1961,7 +1962,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_MissingInfoInNew) {
// Add a third credit card where the expiration date is missing.
FormData form3;
- form3.origin = GURL("https://wwww.foo.com");
+ form3.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form3, "Johnny McEnroe", "5555555555554444",
/* no month */ nullptr,
@@ -2006,7 +2007,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_MissingInfoInOld) {
// Add a second different valid credit card where the year is different but
// the credit card number matches.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111-1111-1111-1111", "01",
/* different year */ "2999");
@@ -2049,7 +2050,7 @@ TEST_F(FormDataImporterTest, ImportCreditCard_SameCardWithSeparators) {
// Import the same card info, but with different separators in the number.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111-1111-1111-1111", "01",
"2999");
@@ -2091,7 +2092,7 @@ TEST_F(FormDataImporterTest,
// Simulate a form submission with conflicting expiration year.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01",
/* different year */ "2999");
@@ -2131,7 +2132,7 @@ TEST_F(FormDataImporterTest,
// Simulate a form submission with the same card.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01",
"2999");
@@ -2153,7 +2154,7 @@ TEST_F(FormDataImporterTest,
// |imported_credit_card_record_type_| should be reset.
// Simulate a form submission with a new card.
FormData form2;
- form2.origin = GURL("https://wwww.foo.com");
+ form2.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form2, "Biggie Smalls", "4012888888881881", "01",
"2999");
@@ -2176,7 +2177,7 @@ TEST_F(FormDataImporterTest,
// |imported_credit_card_record_type_| should still be reset even if
// ImportCreditCard is not called. Simulate a form submission with no card.
FormData form3;
- form3.origin = GURL("https://wwww.foo.com");
+ form3.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -2215,7 +2216,7 @@ TEST_F(FormDataImporterTest,
ImportFormData_ImportCreditCardRecordType_NewCard) {
// Simulate a form submission with a new credit card.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01",
"2999");
@@ -2252,7 +2253,7 @@ TEST_F(FormDataImporterTest,
// Simulate a form submission with the same card.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01",
"2999");
@@ -2289,7 +2290,7 @@ TEST_F(FormDataImporterTest,
// Simulate a form submission with the same masked server card.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01",
"2999");
@@ -2325,7 +2326,7 @@ TEST_F(FormDataImporterTest,
// Simulate a form submission with the same full server card.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "378282246310005", "04",
"2999");
@@ -2348,7 +2349,7 @@ TEST_F(FormDataImporterTest,
ImportFormData_ImportCreditCardRecordType_NoCard_InvalidCardNumber) {
// Simulate a form submission using a credit card with an invalid card number.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1112", "01",
"2999");
@@ -2372,7 +2373,7 @@ TEST_F(FormDataImporterTest,
ImportFormData_ImportCreditCardRecordType_NoCard_ExpiredCard) {
// Simulate a form submission with an expired credit card.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01",
"1999");
@@ -2396,7 +2397,7 @@ TEST_F(FormDataImporterTest,
ImportFormData_ImportCreditCardRecordType_NoCard_NoCardOnForm) {
// Simulate a form submission with no credit card on form.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("First name:", "first_name", "George", "text",
@@ -2438,7 +2439,7 @@ TEST_F(FormDataImporterTest,
// address and the credit card.
TEST_F(FormDataImporterTest, ImportFormData_OneAddressOneCreditCard) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
// Address section.
@@ -2503,7 +2504,7 @@ TEST_F(FormDataImporterTest, ImportFormData_OneAddressOneCreditCard) {
// import the address but does import the credit card.
TEST_F(FormDataImporterTest, ImportFormData_TwoAddressesOneCreditCard) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
// Address section 1.
@@ -2583,7 +2584,7 @@ TEST_F(FormDataImporterTest, ImportFormData_TwoAddressesOneCreditCard) {
// the credit card if addresses are disabled.
TEST_F(FormDataImporterTest, ImportFormData_AddressesDisabledOneCreditCard) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
// Address section.
@@ -2639,7 +2640,7 @@ TEST_F(FormDataImporterTest, ImportFormData_AddressesDisabledOneCreditCard) {
// the address if credit cards are disabled.
TEST_F(FormDataImporterTest, ImportFormData_OneAddressCreditCardDisabled) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
// Address section.
@@ -2699,7 +2700,7 @@ TEST_F(FormDataImporterTest, ImportFormData_OneAddressCreditCardDisabled) {
// if both addressed and credit cards are disabled.
TEST_F(FormDataImporterTest, ImportFormData_AddressCreditCardDisabled) {
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
// Address section.
@@ -2769,7 +2770,7 @@ TEST_F(FormDataImporterTest, DontDuplicateMaskedServerCard) {
// A valid credit card form. A user re-enters one of their masked cards.
// We should not offer to save locally.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "John Dillinger",
@@ -2800,7 +2801,7 @@ TEST_F(FormDataImporterTest, ImportFormData_HiddenCreditCardFormAfterEntered) {
features::kAutofillImportNonFocusableCreditCardForms);
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
@@ -2854,7 +2855,7 @@ TEST_F(FormDataImporterTest,
features::kAutofillImportNonFocusableCreditCardForms);
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
@@ -2913,7 +2914,7 @@ TEST_F(FormDataImporterTest, DontDuplicateFullServerCard) {
// here, either. Since it's unmasked, we know for certain that it's the same
// card.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
@@ -2957,7 +2958,7 @@ TEST_F(FormDataImporterTest,
// A user fills/enters the card's information on a checkout form. Ensure that
// an expiration date match is recorded.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
@@ -3009,7 +3010,7 @@ TEST_F(FormDataImporterTest,
// A user fills/enters the card's information on a checkout form with an empty
// expiration date.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
@@ -3057,7 +3058,7 @@ TEST_F(FormDataImporterTest,
// A user fills/enters the card's information on a checkout form with an empty
// expiration date.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
@@ -3106,7 +3107,7 @@ TEST_F(
// A user fills/enters the card's information on a checkout form with an empty
// expiration date.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
@@ -3151,7 +3152,7 @@ TEST_F(FormDataImporterTest,
// the expiration date of the card. Ensure that an expiration date mismatch
// is recorded.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
@@ -3200,7 +3201,7 @@ TEST_F(FormDataImporterTest,
// A user fills/enters the card's information on a checkout form. Ensure that
// an expiration date match is recorded.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
@@ -3250,7 +3251,7 @@ TEST_F(FormDataImporterTest,
// the expiration date of the card. Ensure that an expiration date mismatch
// is recorded.
FormData form;
- form.origin = GURL("https://wwww.foo.com");
+ form.url = GURL("https://wwww.foo.com");
FormFieldData field;
test::CreateTestFormField("Name on card:", "name_on_card", "Clyde Barrow",
diff --git a/chromium/components/autofill/core/browser/form_structure.cc b/chromium/components/autofill/core/browser/form_structure.cc
index 07adcce22f2..c2af03ad09d 100644
--- a/chromium/components/autofill/core/browser/form_structure.cc
+++ b/chromium/components/autofill/core/browser/form_structure.cc
@@ -9,6 +9,8 @@
#include <algorithm>
#include <map>
#include <memory>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
@@ -37,6 +39,7 @@
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
#include "components/autofill/core/common/autofill_regexes.h"
#include "components/autofill/core/common/autofill_util.h"
@@ -339,6 +342,7 @@ bool AllTypesCaptured(const FormStructure& form,
void EncodePasswordAttributesVote(
const std::pair<PasswordAttribute, bool>& password_attributes_vote,
const size_t password_length_vote,
+ const int password_symbol_vote,
AutofillUploadContents* upload) {
switch (password_attributes_vote.first) {
case PasswordAttribute::kHasLowercaseLetter:
@@ -354,6 +358,8 @@ void EncodePasswordAttributesVote(
break;
case PasswordAttribute::kHasSpecialSymbol:
upload->set_password_has_special_symbol(password_attributes_vote.second);
+ if (password_attributes_vote.second)
+ upload->set_password_special_symbol(password_symbol_vote);
break;
case PasswordAttribute::kPasswordAttributesCount:
NOTREACHED();
@@ -460,6 +466,22 @@ void EncodeFieldMetadataForQuery(const FormFieldData& field,
base::UTF16ToUTF8(field.placeholder));
}
+// Creates the type relationship rules map. The keys represent the type that has
+// rules, and the value represents the list of required types for the given
+// key. In order to respect the rule, only one of the required types is needed.
+// For example, for Autofill to support fields of type
+// "PHONE_HOME_COUNTRY_CODE", there would need to be at least one other field
+// of type "PHONE_HOME_NUMBER" or "PHONE_HOME_CITY_AND_NUMBER".
+const std::unordered_map<ServerFieldType, ServerFieldTypeSet>&
+GetTypeRelationshipMap() {
+ // Initialized and cached on first use.
+ static const auto* const rules =
+ new std::unordered_map<ServerFieldType, ServerFieldTypeSet>(
+ {{PHONE_HOME_COUNTRY_CODE,
+ {PHONE_HOME_NUMBER, PHONE_HOME_CITY_AND_NUMBER}}});
+ return *rules;
+}
+
} // namespace
FormStructure::FormStructure(const FormData& form)
@@ -468,7 +490,7 @@ FormStructure::FormStructure(const FormData& form)
form_name_(form.name),
button_titles_(form.button_titles),
submission_event_(SubmissionIndicatorEvent::NONE),
- source_url_(form.origin),
+ source_url_(form.url),
target_url_(form.action),
main_frame_origin_(form.main_frame_origin),
autofill_count_(0),
@@ -484,6 +506,7 @@ FormStructure::FormStructure(const FormData& form)
all_fields_are_passwords_(!form.fields.empty()),
form_parsed_timestamp_(base::TimeTicks::Now()),
passwords_were_revealed_(false),
+ password_symbol_vote_(0),
developer_engagement_metrics_(0) {
// Copy the form fields.
std::map<base::string16, size_t> unique_names;
@@ -591,7 +614,8 @@ bool FormStructure::EncodeUploadRequest(
if (password_attributes_vote_) {
EncodePasswordAttributesVote(*password_attributes_vote_,
- password_length_vote_, upload);
+ password_length_vote_, password_symbol_vote_,
+ upload);
}
if (IsAutofillFieldMetadataEnabled()) {
@@ -775,7 +799,7 @@ std::vector<FormDataPredictions> FormStructure::GetFieldTypePredictions(
for (const FormStructure* form_structure : form_structures) {
FormDataPredictions form;
form.data.name = form_structure->form_name_;
- form.data.origin = form_structure->source_url_;
+ form.data.url = form_structure->source_url_;
form.data.action = form_structure->target_url_;
form.data.main_frame_origin = form_structure->main_frame_origin_;
form.data.is_form_tag = form_structure->is_form_tag_;
@@ -900,7 +924,7 @@ bool FormStructure::ShouldBeUploaded() const {
void FormStructure::RetrieveFromCache(
const FormStructure& cached_form,
- const bool apply_is_autofilled,
+ const bool should_keep_cached_value,
const bool only_server_and_autofill_state) {
// Map from field signatures to cached fields.
std::map<base::string16, const AutofillField*> cached_fields;
@@ -921,14 +945,23 @@ void FormStructure::RetrieveFromCache(
field->set_only_fill_when_focused(
cached_field->second->only_fill_when_focused());
}
- if (apply_is_autofilled) {
+ if (should_keep_cached_value) {
field->is_autofilled = cached_field->second->is_autofilled;
}
- if (field->form_control_type != "select-one" &&
- field->value == cached_field->second->value) {
- // From the perspective of learning user data, text fields containing
- // default values are equivalent to empty fields.
- field->value = base::string16();
+ if (field->form_control_type != "select-one") {
+ bool is_credit_card_field =
+ AutofillType(cached_field->second->Type().GetStorableType())
+ .group() == CREDIT_CARD;
+ if (should_keep_cached_value && is_credit_card_field &&
+ base::FeatureList::IsEnabled(
+ features::kAutofillImportDynamicForms)) {
+ field->value = cached_field->second->value;
+ value_from_dynamic_change_form_ = true;
+ } else if (field->value == cached_field->second->value) {
+ // From the perspective of learning user data, text fields containing
+ // default values are equivalent to empty fields.
+ field->value = base::string16();
+ }
}
field->set_server_type(cached_field->second->server_type());
field->set_previously_autofilled(
@@ -1221,24 +1254,6 @@ std::set<base::string16> FormStructure::PossibleValues(ServerFieldType type) {
return values;
}
-base::string16 FormStructure::GetUniqueValue(HtmlFieldType type) const {
- base::string16 value;
- for (const auto& field : fields_) {
- if (field->html_type() != type)
- continue;
-
- // More than one value found; abort rather than choosing one arbitrarily.
- if (!value.empty() && !field->value.empty()) {
- value.clear();
- break;
- }
-
- value = field->value;
- }
-
- return value;
-}
-
const AutofillField* FormStructure::field(size_t index) const {
if (index >= fields_.size()) {
NOTREACHED();
@@ -1264,7 +1279,7 @@ size_t FormStructure::active_field_count() const {
FormData FormStructure::ToFormData() const {
FormData data;
data.name = form_name_;
- data.origin = source_url_;
+ data.url = source_url_;
data.action = target_url_;
data.main_frame_origin = main_frame_origin_;
@@ -1277,7 +1292,7 @@ FormData FormStructure::ToFormData() const {
bool FormStructure::operator==(const FormData& form) const {
// TODO(jhawkins): Is this enough to differentiate a form?
- if (form_name_ == form.name && source_url_ == form.origin &&
+ if (form_name_ == form.name && source_url_ == form.url &&
target_url_ == form.action) {
return true;
}
@@ -1719,8 +1734,16 @@ void FormStructure::RationalizeRepeatedFields(
void FormStructure::RationalizeFieldTypePredictions() {
RationalizeCreditCardFieldPredictions();
for (const auto& field : fields_) {
- field->SetTypeTo(field->Type());
+ if (base::FeatureList::IsEnabled(features::kAutofillOffNoServerData) &&
+ !field->should_autocomplete && field->server_type() == NO_SERVER_DATA) {
+ // When the field has autocomplete off, and the server returned no
+ // prediction, then assume Autofill is not useful for the current field.
+ field->SetTypeTo(AutofillType(UNKNOWN_TYPE));
+ } else {
+ field->SetTypeTo(field->Type());
+ }
}
+ RationalizeTypeRelationships();
}
void FormStructure::EncodeFormForQuery(
@@ -2031,4 +2054,38 @@ void FormStructure::set_randomized_encoder(
randomized_encoder_ = std::move(encoder);
}
+void FormStructure::RationalizeTypeRelationships() {
+ // Create a local set of all the types for faster lookup.
+ std::unordered_set<ServerFieldType> types;
+ for (const auto& field : fields_) {
+ types.insert(field->Type().GetStorableType());
+ }
+
+ const auto& type_relationship_rules = GetTypeRelationshipMap();
+
+ for (const auto& field : fields_) {
+ ServerFieldType field_type = field->Type().GetStorableType();
+ const auto& ruleset_iterator = type_relationship_rules.find(field_type);
+ if (ruleset_iterator != type_relationship_rules.end()) {
+ // We have relationship rules for this type. Verify that at least one of
+ // the required related type is present.
+ bool found = false;
+ for (ServerFieldType required_type : ruleset_iterator->second) {
+ if (types.find(required_type) != types.end()) {
+ // Found a required type, we can break as we only need one required
+ // type to respect the rule.
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ // No required type was found, the current field failed the relationship
+ // requirements for its type. Disabling Autofill for this field.
+ field->SetTypeTo(AutofillType(UNKNOWN_TYPE));
+ }
+ }
+ }
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/form_structure.h b/chromium/components/autofill/core/browser/form_structure.h
index 414345d7744..df85abceb14 100644
--- a/chromium/components/autofill/core/browser/form_structure.h
+++ b/chromium/components/autofill/core/browser/form_structure.h
@@ -11,6 +11,7 @@
#include <memory>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "base/gtest_prod_util.h"
@@ -147,7 +148,7 @@ class FormStructure {
// Sets the field types to be those set for |cached_form|.
void RetrieveFromCache(const FormStructure& cached_form,
- const bool apply_is_autofilled,
+ const bool should_keep_cached_value,
const bool only_server_and_autofill_state);
// Logs quality metrics for |this|, which should be a user-submitted form.
@@ -194,10 +195,6 @@ class FormStructure {
// All returned values are standardized to upper case.
std::set<base::string16> PossibleValues(ServerFieldType type);
- // Gets the form's current value for |type|. For example, it may return
- // the contents of a text input or the currently selected <option>.
- base::string16 GetUniqueValue(HtmlFieldType type) const;
-
// Rationalize phone number fields in a given section, that is only fill
// the fields that are considered composing a first complete phone number.
void RationalizePhoneNumbersInSection(std::string section);
@@ -305,11 +302,26 @@ class FormStructure {
}
#endif
+ void set_password_symbol_vote(int noisified_symbol) {
+ DCHECK(password_attributes_vote_.has_value())
+ << "password_symbol_vote_| doesn't make sense if "
+ "|password_attributes_vote_| has no value.";
+ password_symbol_vote_ = noisified_symbol;
+ }
+
+#if defined(UNIT_TEST)
+ int get_password_symbol_vote_for_testing() {
+ DCHECK(password_attributes_vote_.has_value())
+ << "|password_symbol_vote_| doesn't make sense if "
+ "|password_attributes_vote_| has no value";
+ return password_symbol_vote_;
+ }
+#endif
+
SubmissionSource submission_source() const { return submission_source_; }
void set_submission_source(SubmissionSource submission_source) {
submission_source_ = submission_source;
}
-
bool operator==(const FormData& form) const;
bool operator!=(const FormData& form) const;
@@ -331,6 +343,14 @@ class FormStructure {
page_language_ = std::move(language);
}
+ bool value_from_dynamic_change_form() const {
+ return value_from_dynamic_change_form_;
+ }
+
+ void set_value_from_dynamic_change_form(bool v) {
+ value_from_dynamic_change_form_ = v;
+ }
+
private:
friend class AutofillMergeTest;
friend class FormStructureTest;
@@ -438,6 +458,10 @@ class FormStructure {
// Tunes the fields with identical predictions.
void RationalizeRepeatedFields(AutofillMetrics::FormInteractionsUkmLogger*);
+ // Filters out fields that don't meet the relationship ruleset for their type
+ // defined in |type_relationships_rules_|.
+ void RationalizeTypeRelationships();
+
// A helper function to review the predictions and do appropriate adjustments
// when it considers necessary.
void RationalizeFieldTypePredictions();
@@ -568,6 +592,12 @@ class FormStructure {
// character).
base::Optional<std::pair<PasswordAttribute, bool>> password_attributes_vote_;
+ // If |password_attribute_vote_| contains (kHasSpecialSymbol, true), this
+ // field contains nosified information about a special symbol in a
+ // user-created password stored as ASCII code. The default value of 0
+ // indicates that no symbol was set.
+ int password_symbol_vote_;
+
// Noisified password length for crowdsourcing. If |password_attributes_vote_|
// has no value, |password_length_vote_| should be ignored.
size_t password_length_vote_;
@@ -587,6 +617,8 @@ class FormStructure {
// form/field metadata.
bool is_rich_query_enabled_ = false;
+ bool value_from_dynamic_change_form_ = false;
+
DISALLOW_COPY_AND_ASSIGN(FormStructure);
};
diff --git a/chromium/components/autofill/core/browser/form_structure_unittest.cc b/chromium/components/autofill/core/browser/form_structure_unittest.cc
index cdc3cd526ad..cff3806b32f 100644
--- a/chromium/components/autofill/core/browser/form_structure_unittest.cc
+++ b/chromium/components/autofill/core/browser/form_structure_unittest.cc
@@ -143,10 +143,14 @@ class FormStructureTest : public testing::Test {
scoped_refptr<base::FieldTrial> field_trial_;
};
+class ParameterizedFormStructureTest
+ : public FormStructureTest,
+ public testing::WithParamInterface<bool> {};
+
TEST_F(FormStructureTest, FieldCount) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.label = ASCIIToUTF16("username");
@@ -179,7 +183,7 @@ TEST_F(FormStructureTest, FieldCount) {
TEST_F(FormStructureTest, AutofillCount) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.label = ASCIIToUTF16("username");
@@ -232,15 +236,15 @@ TEST_F(FormStructureTest, AutofillCount) {
TEST_F(FormStructureTest, SourceURL) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormStructure form_structure(form);
- EXPECT_EQ(form.origin, form_structure.source_url());
+ EXPECT_EQ(form.url, form_structure.source_url());
}
TEST_F(FormStructureTest, IsAutofillable) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
// Start with a username field. It should be picked up by the password but
@@ -308,7 +312,7 @@ TEST_F(FormStructureTest, IsAutofillable) {
TEST_F(FormStructureTest, ShouldBeParsed) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
// Start with a single checkable field.
FormFieldData checkable_field;
@@ -426,7 +430,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_BadScheme) {
form.fields.push_back(field);
// Baseline, HTTP should work.
- form.origin = GURL("http://wwww.foo.com/myform");
+ form.url = GURL("http://wwww.foo.com/myform");
form_structure = std::make_unique<FormStructure>(form);
form_structure->ParseFieldTypesFromAutocompleteAttributes();
EXPECT_TRUE(form_structure->ShouldBeParsed());
@@ -435,7 +439,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_BadScheme) {
EXPECT_TRUE(form_structure->ShouldBeUploaded());
// Baseline, HTTPS should work.
- form.origin = GURL("https://wwww.foo.com/myform");
+ form.url = GURL("https://wwww.foo.com/myform");
form_structure = std::make_unique<FormStructure>(form);
form_structure->ParseFieldTypesFromAutocompleteAttributes();
EXPECT_TRUE(form_structure->ShouldBeParsed());
@@ -444,7 +448,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_BadScheme) {
EXPECT_TRUE(form_structure->ShouldBeUploaded());
// Chrome internal urls shouldn't be parsed.
- form.origin = GURL("chrome://settings");
+ form.url = GURL("chrome://settings");
form_structure = std::make_unique<FormStructure>(form);
form_structure->ParseFieldTypesFromAutocompleteAttributes();
EXPECT_FALSE(form_structure->ShouldBeParsed());
@@ -453,7 +457,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_BadScheme) {
EXPECT_FALSE(form_structure->ShouldBeUploaded());
// FTP urls shouldn't be parsed.
- form.origin = GURL("ftp://ftp.foo.com/form.html");
+ form.url = GURL("ftp://ftp.foo.com/form.html");
form_structure = std::make_unique<FormStructure>(form);
form_structure->ParseFieldTypesFromAutocompleteAttributes();
EXPECT_FALSE(form_structure->ShouldBeParsed());
@@ -462,7 +466,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_BadScheme) {
EXPECT_FALSE(form_structure->ShouldBeUploaded());
// Blob urls shouldn't be parsed.
- form.origin = GURL("blob://blob.foo.com/form.html");
+ form.url = GURL("blob://blob.foo.com/form.html");
form_structure = std::make_unique<FormStructure>(form);
form_structure->ParseFieldTypesFromAutocompleteAttributes();
EXPECT_FALSE(form_structure->ShouldBeParsed());
@@ -471,7 +475,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_BadScheme) {
EXPECT_FALSE(form_structure->ShouldBeUploaded());
// About urls shouldn't be parsed.
- form.origin = GURL("about://about.foo.com/form.html");
+ form.url = GURL("about://about.foo.com/form.html");
form_structure = std::make_unique<FormStructure>(form);
form_structure->ParseFieldTypesFromAutocompleteAttributes();
EXPECT_FALSE(form_structure->ShouldBeParsed());
@@ -485,7 +489,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_BadScheme) {
TEST_F(FormStructureTest, ShouldBeParsed_TwoFields_HasAutocomplete) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.label = ASCIIToUTF16("Name");
@@ -510,7 +514,7 @@ TEST_F(FormStructureTest, ShouldBeParsed_TwoFields_HasAutocomplete) {
TEST_F(FormStructureTest, DetermineHeuristicTypes_AutocompleteFalse) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.label = ASCIIToUTF16("Name");
@@ -544,7 +548,7 @@ TEST_F(FormStructureTest, DetermineHeuristicTypes_AutocompleteFalse) {
TEST_F(FormStructureTest, HeuristicsContactInfo) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -619,7 +623,7 @@ TEST_F(FormStructureTest, HeuristicsContactInfo) {
TEST_F(FormStructureTest, HeuristicsAutocompleteAttribute) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -671,7 +675,7 @@ TEST_F(FormStructureTest, Heuristics_FormlessNonCheckoutForm) {
features::kAutofillRestrictUnownedFieldsToFormlessCheckout);
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -724,7 +728,7 @@ TEST_F(FormStructureTest, Heuristics_FormlessNonCheckoutForm) {
// that the common prefix is stripped out before running heuristics.
TEST_F(FormStructureTest, StripCommonNamePrefix) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -775,7 +779,7 @@ TEST_F(FormStructureTest, StripCommonNamePrefix) {
// stripped from the name before running the heuristics.
TEST_F(FormStructureTest, StripCommonNamePrefix_SmallPrefix) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -811,7 +815,7 @@ TEST_F(FormStructureTest, StripCommonNamePrefix_SmallPrefix) {
TEST_F(FormStructureTest, IsCompleteCreditCardForm_Minimal) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -838,7 +842,7 @@ TEST_F(FormStructureTest, IsCompleteCreditCardForm_Minimal) {
TEST_F(FormStructureTest, IsCompleteCreditCardForm_Full) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -878,7 +882,7 @@ TEST_F(FormStructureTest, IsCompleteCreditCardForm_Full) {
TEST_F(FormStructureTest, IsCompleteCreditCardForm_OnlyCCNumber) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -897,7 +901,7 @@ TEST_F(FormStructureTest, IsCompleteCreditCardForm_OnlyCCNumber) {
TEST_F(FormStructureTest, IsCompleteCreditCardForm_AddressForm) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -940,7 +944,7 @@ TEST_F(FormStructureTest, IsCompleteCreditCardForm_AddressForm) {
TEST_F(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -984,7 +988,7 @@ TEST_F(FormStructureTest,
HeuristicsAndServerPredictions_BigForm_NoAutocompleteAttribute) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1021,7 +1025,7 @@ TEST_F(FormStructureTest,
HeuristicsAndServerPredictions_ValidAutocompleteAttribute) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1062,7 +1066,7 @@ TEST_F(FormStructureTest,
HeuristicsAndServerPredictions_UnrecognizedAutocompleteAttribute) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1105,7 +1109,7 @@ TEST_F(FormStructureTest,
TEST_F(FormStructureTest,
HeuristicsAndServerPredictions_SmallForm_NoAutocompleteAttribute) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1179,7 +1183,7 @@ TEST_F(FormStructureTest,
TEST_F(FormStructureTest,
HeuristicsAndServerPredictions_SmallForm_ValidAutocompleteAttribute) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1266,7 +1270,7 @@ TEST_F(FormStructureTest,
// considered autofillable though.
TEST_F(FormStructureTest, PasswordFormShouldBeQueried) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
// Start with a regular contact form.
FormFieldData field;
@@ -1301,7 +1305,7 @@ TEST_F(FormStructureTest, PasswordFormShouldBeQueried) {
// attribute.
TEST_F(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1366,7 +1370,7 @@ TEST_F(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) {
TEST_F(FormStructureTest,
HeuristicsAutocompleteAttributeWithSectionsDegenerate) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1410,7 +1414,7 @@ TEST_F(FormStructureTest,
// |autocomplete| attribute.
TEST_F(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsRepeated) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1440,7 +1444,7 @@ TEST_F(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsRepeated) {
// local heuristics.
TEST_F(FormStructureTest, HeuristicsDontOverrideAutocompleteAttributeSections) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1476,7 +1480,7 @@ TEST_F(FormStructureTest, HeuristicsDontOverrideAutocompleteAttributeSections) {
TEST_F(FormStructureTest, HeuristicsSample8) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1554,7 +1558,7 @@ TEST_F(FormStructureTest, HeuristicsSample8) {
TEST_F(FormStructureTest, HeuristicsSample6) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1617,7 +1621,7 @@ TEST_F(FormStructureTest, HeuristicsSample6) {
TEST_F(FormStructureTest, HeuristicsLabelsOnly) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1683,7 +1687,7 @@ TEST_F(FormStructureTest, HeuristicsLabelsOnly) {
TEST_F(FormStructureTest, HeuristicsCreditCardInfo) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1738,7 +1742,7 @@ TEST_F(FormStructureTest, HeuristicsCreditCardInfo) {
TEST_F(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1801,7 +1805,7 @@ TEST_F(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
TEST_F(FormStructureTest, ThreeAddressLines) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1842,7 +1846,7 @@ TEST_F(FormStructureTest, ThreeAddressLines) {
TEST_F(FormStructureTest, SurplusAddressLinesIgnored) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1886,7 +1890,7 @@ TEST_F(FormStructureTest, SurplusAddressLinesIgnored) {
TEST_F(FormStructureTest, ThreeAddressLinesExpedia) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1929,7 +1933,7 @@ TEST_F(FormStructureTest, ThreeAddressLinesExpedia) {
TEST_F(FormStructureTest, TwoAddressLinesEbay) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1963,7 +1967,7 @@ TEST_F(FormStructureTest, TwoAddressLinesEbay) {
TEST_F(FormStructureTest, HeuristicsStateWithProvince) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -1998,7 +2002,7 @@ TEST_F(FormStructureTest, HeuristicsStateWithProvince) {
TEST_F(FormStructureTest, HeuristicsWithBilling) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -2070,7 +2074,7 @@ TEST_F(FormStructureTest, HeuristicsWithBilling) {
TEST_F(FormStructureTest, ThreePartPhoneNumber) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -2116,7 +2120,7 @@ TEST_F(FormStructureTest, ThreePartPhoneNumber) {
TEST_F(FormStructureTest, HeuristicsInfernoCC) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -2167,7 +2171,7 @@ TEST_F(FormStructureTest, HeuristicsInfernoCC) {
TEST_F(FormStructureTest, HeuristicsInferCCNames_NamesNotFirst) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -2226,7 +2230,7 @@ TEST_F(FormStructureTest, HeuristicsInferCCNames_NamesNotFirst) {
TEST_F(FormStructureTest, HeuristicsInferCCNames_NamesFirst) {
std::unique_ptr<FormStructure> form_structure;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -2281,7 +2285,7 @@ TEST_F(FormStructureTest, HeuristicsInferCCNames_NamesFirst) {
TEST_F(FormStructureTest, EncodeQueryRequest) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.form_control_type = "text";
@@ -2443,7 +2447,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_WithMatchingValidities) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -2638,7 +2642,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_WithNonMatchingValidities) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form_structure = std::make_unique<FormStructure>(form);
form_structure->DetermineHeuristicTypes();
@@ -2766,7 +2770,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_WithMultipleValidities) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -2895,7 +2899,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3108,7 +3112,7 @@ TEST_F(FormStructureTest,
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3234,7 +3238,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_WithAutocomplete) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3318,7 +3322,7 @@ TEST_F(FormStructureTest, EncodeUploadRequestWithPropertiesMask) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3418,7 +3422,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_ObservedSubmissionFalse) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3501,7 +3505,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_WithLabels) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3575,7 +3579,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_WithCssClassesAndIds) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
FormFieldData field;
@@ -3657,7 +3661,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_WithFormName) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
// Setting the form name which we expect to see in the upload.
@@ -3734,7 +3738,7 @@ TEST_F(FormStructureTest, EncodeUploadRequestPartialMetadata) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3819,7 +3823,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_DisabledMetadataTrial) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
form_structure = std::make_unique<FormStructure>(form);
@@ -3908,7 +3912,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_DisabledMetadataTrial) {
// |available_types|.
TEST_F(FormStructureTest, CheckDataPresence) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = true;
FormFieldData field;
@@ -4188,7 +4192,7 @@ TEST_F(FormStructureTest, CheckMultipleTypes) {
std::vector<ServerFieldTypeSet> possible_field_types;
std::vector<ServerFieldTypeValidityStatesMap> possible_field_types_validities;
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
form.is_form_tag = false;
FormFieldData field;
@@ -4331,7 +4335,7 @@ TEST_F(FormStructureTest, CheckMultipleTypes) {
TEST_F(FormStructureTest, EncodeUploadRequest_PasswordsRevealed) {
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
// Add 3 fields, to make the form uploadable.
FormFieldData field;
@@ -4362,7 +4366,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_IsFormTag) {
SCOPED_TRACE(testing::Message() << "is_form_tag=" << is_form_tag);
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
FormFieldData field;
field.name = ASCIIToUTF16("email");
form.fields.push_back(field);
@@ -4397,7 +4401,7 @@ TEST_F(FormStructureTest, EncodeUploadRequest_RichMetadata) {
};
FormData form;
- form.origin = GURL("http://www.foo.com/");
+ form.url = GURL("http://www.foo.com/");
for (const auto& f : kFieldMetadata) {
FormFieldData field;
field.id_attribute = ASCIIToUTF16(f.id);
@@ -4499,7 +4503,7 @@ TEST_F(FormStructureTest, CheckFormSignature) {
EXPECT_EQ(FormStructureTest::Hash64Bit(std::string("://&&email&first")),
form_structure->FormSignatureAsStr());
- form.origin = GURL(std::string("http://www.facebook.com"));
+ form.url = GURL(std::string("http://www.facebook.com"));
form_structure = std::make_unique<FormStructure>(form);
EXPECT_EQ(FormStructureTest::Hash64Bit(
std::string("http://www.facebook.com&&email&first")),
@@ -4542,8 +4546,8 @@ TEST_F(FormStructureTest, CheckFormSignature) {
TEST_F(FormStructureTest, ToFormData) {
FormData form;
form.name = ASCIIToUTF16("the-name");
- form.origin = GURL("http://cool.com");
- form.action = form.origin.Resolve("/login");
+ form.url = GURL("http://cool.com");
+ form.action = form.url.Resolve("/login");
FormFieldData field;
field.label = ASCIIToUTF16("username");
@@ -4567,8 +4571,8 @@ TEST_F(FormStructureTest, ToFormData) {
TEST_F(FormStructureTest, SkipFieldTest) {
FormData form;
form.name = ASCIIToUTF16("the-name");
- form.origin = GURL("http://cool.com");
- form.action = form.origin.Resolve("/login");
+ form.url = GURL("http://cool.com");
+ form.action = form.url.Resolve("/login");
FormFieldData field;
field.label = ASCIIToUTF16("username");
@@ -4621,8 +4625,8 @@ TEST_F(FormStructureTest, SkipFieldTest) {
TEST_F(FormStructureTest, EncodeQueryRequest_WithLabels) {
FormData form;
form.name = ASCIIToUTF16("the-name");
- form.origin = GURL("http://cool.com");
- form.action = form.origin.Resolve("/login");
+ form.url = GURL("http://cool.com");
+ form.action = form.url.Resolve("/login");
FormFieldData field;
// No label on the first field.
@@ -4671,8 +4675,8 @@ TEST_F(FormStructureTest, EncodeQueryRequest_WithLabels) {
TEST_F(FormStructureTest, EncodeQueryRequest_WithLongLabels) {
FormData form;
form.name = ASCIIToUTF16("the-name");
- form.origin = GURL("http://cool.com");
- form.action = form.origin.Resolve("/login");
+ form.url = GURL("http://cool.com");
+ form.action = form.url.Resolve("/login");
FormFieldData field;
// No label on the first field.
@@ -4727,8 +4731,8 @@ TEST_F(FormStructureTest, EncodeQueryRequest_WithLongLabels) {
TEST_F(FormStructureTest, EncodeQueryRequest_MissingNames) {
FormData form;
// No name set for the form.
- form.origin = GURL("http://cool.com");
- form.action = form.origin.Resolve("/login");
+ form.url = GURL("http://cool.com");
+ form.action = form.url.Resolve("/login");
FormFieldData field;
field.label = ASCIIToUTF16("username");
@@ -4780,8 +4784,8 @@ TEST_F(FormStructureTest, EncodeQueryRequest_DisabledMetadataTrial) {
FormData form;
// No name set for the form.
- form.origin = GURL("http://cool.com");
- form.action = form.origin.Resolve("/login");
+ form.url = GURL("http://cool.com");
+ form.action = form.url.Resolve("/login");
FormFieldData field;
field.label = ASCIIToUTF16("username");
@@ -4827,7 +4831,7 @@ TEST_F(FormStructureTest, EncodeQueryRequest_DisabledMetadataTrial) {
TEST_F(FormStructureTest, PossibleValues) {
FormData form_data;
- form_data.origin = GURL("http://www.foo.com/");
+ form_data.url = GURL("http://www.foo.com/");
FormFieldData field;
field.autocomplete_attribute = "billing country";
@@ -4871,7 +4875,7 @@ TEST_F(FormStructureTest, PossibleValues) {
TEST_F(FormStructureTest, ParseQueryResponse_UnknownType) {
FormData form_data;
FormFieldData field;
- form_data.origin = GURL("http://foo.com");
+ form_data.url = GURL("http://foo.com");
field.form_control_type = "text";
field.label = ASCIIToUTF16("First Name");
@@ -4926,7 +4930,7 @@ TEST_F(FormStructureTest, ParseQueryResponse_UnknownType) {
// proto.
TEST_F(FormStructureTest, ParseQueryResponse) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
@@ -4998,7 +5002,7 @@ TEST_F(FormStructureTest, ParseQueryResponse) {
TEST_F(FormStructureTest, ParseApiQueryResponse) {
// Make form 1 data.
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
@@ -5087,7 +5091,7 @@ TEST_F(FormStructureTest, ParseApiQueryResponse) {
TEST_F(FormStructureTest, ParseApiQueryResponseWhenCannotParseProtoFromString) {
// Make form 1 data.
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "email";
field.label = ASCIIToUTF16("emailaddress");
@@ -5115,7 +5119,7 @@ TEST_F(FormStructureTest, ParseApiQueryResponseWhenCannotParseProtoFromString) {
TEST_F(FormStructureTest, ParseApiQueryResponseWhenPayloadNotBase64) {
// Make form 1 data.
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "email";
field.label = ASCIIToUTF16("emailaddress");
@@ -5154,7 +5158,7 @@ TEST_F(FormStructureTest, ParseApiQueryResponseWhenPayloadNotBase64) {
TEST_F(FormStructureTest, ParseQueryResponse_AuthorDefinedTypes) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.label = ASCIIToUTF16("email");
@@ -5194,7 +5198,7 @@ TEST_F(FormStructureTest, ParseQueryResponse_AuthorDefinedTypes) {
TEST_F(FormStructureTest, ParseQueryResponse_RationalizeLoneField) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
@@ -5240,7 +5244,7 @@ TEST_F(FormStructureTest, ParseQueryResponse_RationalizeLoneField) {
TEST_F(FormStructureTest, ParseQueryResponse_RationalizeCCName) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
@@ -5279,7 +5283,7 @@ TEST_F(FormStructureTest, ParseQueryResponse_RationalizeCCName) {
TEST_F(FormStructureTest, ParseQueryResponse_RationalizeMultiMonth_1) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
@@ -5335,7 +5339,7 @@ TEST_F(FormStructureTest, ParseQueryResponse_RationalizeMultiMonth_1) {
TEST_F(FormStructureTest, ParseQueryResponse_RationalizeMultiMonth_2) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
@@ -5424,7 +5428,7 @@ TEST_F(FormStructureTest, FindLongestCommonPrefix) {
TEST_F(FormStructureTest, RationalizePhoneNumber_RunsOncePerSection) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -5479,7 +5483,7 @@ TEST_F(FormStructureTest, RationalizePhoneNumber_RunsOncePerSection) {
// ADDRESS_HOME_STREET_ADDRESS is not modified by the address rationalization.
TEST_F(FormStructureTest, RationalizeRepeatedFields_OneAddress) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -5525,7 +5529,7 @@ TEST_F(FormStructureTest, RationalizeRepeatedFields_OneAddress) {
// ADDRESS_HOME_LINE1 and ADDRESS_HOME_LINE2 instead.
TEST_F(FormStructureTest, RationalizeRepreatedFields_TwoAddresses) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -5577,7 +5581,7 @@ TEST_F(FormStructureTest, RationalizeRepreatedFields_TwoAddresses) {
// ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2 and ADDRESS_HOME_LINE3 instead.
TEST_F(FormStructureTest, RationalizeRepreatedFields_ThreeAddresses) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -5637,7 +5641,7 @@ TEST_F(FormStructureTest, RationalizeRepreatedFields_ThreeAddresses) {
// sections according to the heuristics.
TEST_F(FormStructureTest, RationalizeRepreatedFields_FourAddresses) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -5706,7 +5710,7 @@ TEST_F(FormStructureTest, RationalizeRepreatedFields_FourAddresses) {
// ADDRESS_HOME_STREET_ADDRESS is not modified by the address rationalization.
TEST_F(FormStructureTest, RationalizeRepreatedFields_OneAddressEachSection) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -5784,7 +5788,7 @@ TEST_F(
FormStructureTest,
RationalizeRepreatedFields_SectionTwoAddress_SectionThreeAddress_SectionFourAddresses) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -5937,7 +5941,7 @@ TEST_F(
TEST_F(FormStructureTest,
RationalizeRepreatedFields_MultipleSectionsByHeuristics_OneAddressEach) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -6010,7 +6014,7 @@ TEST_F(
FormStructureTest,
RationalizeRepreatedFields_MultipleSectionsByHeuristics_TwoAddress_ThreeAddress) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -6099,7 +6103,7 @@ TEST_F(
TEST_F(FormStructureTest,
RationalizeRepreatedFields_StateCountry_NoRationalization) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -6194,7 +6198,7 @@ TEST_F(FormStructureTest,
TEST_F(FormStructureTest, RationalizeRepreatedFields_CountryStateNoHeuristics) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -6325,7 +6329,7 @@ TEST_F(FormStructureTest, RationalizeRepreatedFields_CountryStateNoHeuristics) {
TEST_F(FormStructureTest,
RationalizeRepreatedFields_StateCountryWithHeuristics) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -6456,7 +6460,7 @@ TEST_F(FormStructureTest,
TEST_F(FormStructureTest, RationalizeRepreatedFields_FirstFieldRationalized) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -6517,7 +6521,7 @@ TEST_F(FormStructureTest, RationalizeRepreatedFields_FirstFieldRationalized) {
TEST_F(FormStructureTest, RationalizeRepreatedFields_LastFieldRationalized) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
field.form_control_type = "text";
field.max_length = 10000;
@@ -6584,9 +6588,227 @@ TEST_F(FormStructureTest, RationalizeRepreatedFields_LastFieldRationalized) {
EXPECT_EQ(ADDRESS_HOME_STATE, forms[0]->field(5)->Type().GetStorableType());
}
+INSTANTIATE_TEST_SUITE_P(, ParameterizedFormStructureTest, testing::Bool());
+
+// Tests that, when the flag is off, we will not set the predicted type to
+// unknown for fields that have no server data and autocomplete off, and when
+// the flag is ON, we will overwrite the predicted type.
+TEST_P(ParameterizedFormStructureTest,
+ NoServerData_AutocompleteOff_FlagDisabled_NoOverwrite) {
+ base::test::ScopedFeatureList scoped_features;
+
+ bool flag_enabled = GetParam();
+ scoped_features.InitWithFeatureState(features::kAutofillOffNoServerData,
+ flag_enabled);
+
+ FormData form;
+ form.url = GURL("http://foo.com");
+ FormFieldData field;
+ field.form_control_type = "text";
+ field.max_length = 10000;
+ field.should_autocomplete = false;
+
+ // Autocomplete Off, with server data.
+ field.label = ASCIIToUTF16("First Name");
+ field.name = ASCIIToUTF16("firstName");
+ form.fields.push_back(field);
+
+ // Autocomplete Off, without server data.
+ field.label = ASCIIToUTF16("Last Name");
+ field.name = ASCIIToUTF16("lastName");
+ form.fields.push_back(field);
+
+ // Autocomplete On, with server data.
+ field.should_autocomplete = true;
+ field.label = ASCIIToUTF16("Address");
+ field.name = ASCIIToUTF16("address");
+ form.fields.push_back(field);
+
+ // Autocomplete On, without server data.
+ field.label = ASCIIToUTF16("Country");
+ field.name = ASCIIToUTF16("country");
+ form.fields.push_back(field);
+
+ AutofillQueryResponseContents response;
+ response.add_field()->set_overall_type_prediction(NAME_FIRST);
+ response.add_field()->set_overall_type_prediction(NO_SERVER_DATA);
+ response.add_field()->set_overall_type_prediction(NO_SERVER_DATA);
+ response.add_field()->set_overall_type_prediction(NO_SERVER_DATA);
+
+ std::string response_string;
+ ASSERT_TRUE(response.SerializeToString(&response_string));
+
+ FormStructure form_structure(form);
+
+ // Will identify the sections based on the heuristics types.
+ form_structure.DetermineHeuristicTypes();
+
+ std::vector<FormStructure*> forms;
+ forms.push_back(&form_structure);
+
+ // Will call RationalizeFieldTypePredictions
+ FormStructure::ParseQueryResponse(response_string, forms, nullptr);
+
+ ASSERT_EQ(1U, forms.size());
+ ASSERT_EQ(4U, forms[0]->field_count());
+
+ // Only NAME_LAST should be affected by the flag.
+ EXPECT_EQ(flag_enabled ? UNKNOWN_TYPE : NAME_LAST,
+ forms[0]->field(1)->Type().GetStorableType());
+
+ EXPECT_EQ(NAME_FIRST, forms[0]->field(0)->Type().GetStorableType());
+ EXPECT_EQ(ADDRESS_HOME_LINE1, forms[0]->field(2)->Type().GetStorableType());
+ EXPECT_EQ(ADDRESS_HOME_COUNTRY, forms[0]->field(3)->Type().GetStorableType());
+}
+
+struct RationalizationTypeRelationshipsTestParams {
+ ServerFieldType server_type;
+ ServerFieldType required_type;
+};
+class RationalizationFieldTypeFilterTest
+ : public FormStructureTest,
+ public testing::WithParamInterface<ServerFieldType> {};
+class RationalizationFieldTypeRelationshipsTest
+ : public FormStructureTest,
+ public testing::WithParamInterface<
+ RationalizationTypeRelationshipsTestParams> {};
+
+INSTANTIATE_TEST_SUITE_P(,
+ RationalizationFieldTypeFilterTest,
+ testing::Values(PHONE_HOME_COUNTRY_CODE));
+
+INSTANTIATE_TEST_SUITE_P(,
+ RationalizationFieldTypeRelationshipsTest,
+ testing::Values(
+ RationalizationTypeRelationshipsTestParams{
+ PHONE_HOME_COUNTRY_CODE, PHONE_HOME_NUMBER},
+ RationalizationTypeRelationshipsTestParams{
+ PHONE_HOME_COUNTRY_CODE,
+ PHONE_HOME_CITY_AND_NUMBER}));
+
+// Tests that the rationalization logic will filter out fields of type |param|
+// when there is no other required type.
+TEST_P(RationalizationFieldTypeFilterTest, Rationalization_Rules_Filter_Out) {
+ ServerFieldType filtered_off_field = GetParam();
+
+ FormData form;
+ form.url = GURL("http://foo.com");
+ FormFieldData field;
+ field.form_control_type = "text";
+ field.max_length = 10000;
+ field.should_autocomplete = true;
+
+ // Just adding >=3 random fields to trigger rationalization.
+ field.label = ASCIIToUTF16("First Name");
+ field.name = ASCIIToUTF16("firstName");
+ form.fields.push_back(field);
+ field.label = ASCIIToUTF16("Last Name");
+ field.name = ASCIIToUTF16("lastName");
+ form.fields.push_back(field);
+ field.label = ASCIIToUTF16("Address");
+ field.name = ASCIIToUTF16("address");
+ form.fields.push_back(field);
+
+ field.label = ASCIIToUTF16("Something under test");
+ field.name = ASCIIToUTF16("tested-thing");
+ form.fields.push_back(field);
+
+ AutofillQueryResponseContents response;
+ response.add_field()->set_overall_type_prediction(NAME_FIRST);
+ response.add_field()->set_overall_type_prediction(NAME_LAST);
+ response.add_field()->set_overall_type_prediction(ADDRESS_HOME_LINE1);
+ response.add_field()->set_overall_type_prediction(filtered_off_field);
+
+ std::string response_string;
+ ASSERT_TRUE(response.SerializeToString(&response_string));
+
+ FormStructure form_structure(form);
+
+ // Will identify the sections based on the heuristics types.
+ form_structure.DetermineHeuristicTypes();
+
+ std::vector<FormStructure*> forms;
+ forms.push_back(&form_structure);
+
+ // Will call RationalizeFieldTypePredictions
+ FormStructure::ParseQueryResponse(response_string, forms, nullptr);
+
+ ASSERT_EQ(1U, forms.size());
+ ASSERT_EQ(4U, forms[0]->field_count());
+
+ EXPECT_EQ(NAME_FIRST, forms[0]->field(0)->Type().GetStorableType());
+ EXPECT_EQ(NAME_LAST, forms[0]->field(1)->Type().GetStorableType());
+ EXPECT_EQ(ADDRESS_HOME_LINE1, forms[0]->field(2)->Type().GetStorableType());
+
+ // Last field's type should have been overwritten to expected.
+ EXPECT_EQ(UNKNOWN_TYPE, forms[0]->field(3)->Type().GetStorableType());
+}
+
+// Tests that the rationalization logic will not filter out fields of type
+// |param| when there is another field with a required type.
+TEST_P(RationalizationFieldTypeRelationshipsTest,
+ Rationalization_Rules_Relationships) {
+ RationalizationTypeRelationshipsTestParams test_params = GetParam();
+
+ FormData form;
+ form.url = GURL("http://foo.com");
+ FormFieldData field;
+ field.form_control_type = "text";
+ field.max_length = 10000;
+ field.should_autocomplete = true;
+
+ // Just adding >=3 random fields to trigger rationalization.
+ field.label = ASCIIToUTF16("First Name");
+ field.name = ASCIIToUTF16("firstName");
+ form.fields.push_back(field);
+ field.label = ASCIIToUTF16("Last Name");
+ field.name = ASCIIToUTF16("lastName");
+ form.fields.push_back(field);
+
+ field.label = ASCIIToUTF16("Some field with required type");
+ field.name = ASCIIToUTF16("some-name");
+ form.fields.push_back(field);
+
+ field.label = ASCIIToUTF16("Something under test");
+ field.name = ASCIIToUTF16("tested-thing");
+ form.fields.push_back(field);
+
+ AutofillQueryResponseContents response;
+ response.add_field()->set_overall_type_prediction(NAME_FIRST);
+ response.add_field()->set_overall_type_prediction(NAME_LAST);
+ response.add_field()->set_overall_type_prediction(test_params.required_type);
+ response.add_field()->set_overall_type_prediction(test_params.server_type);
+
+ std::string response_string;
+ ASSERT_TRUE(response.SerializeToString(&response_string));
+
+ FormStructure form_structure(form);
+
+ // Will identify the sections based on the heuristics types.
+ form_structure.DetermineHeuristicTypes();
+
+ std::vector<FormStructure*> forms;
+ forms.push_back(&form_structure);
+
+ // Will call RationalizeFieldTypePredictions
+ FormStructure::ParseQueryResponse(response_string, forms, nullptr);
+
+ ASSERT_EQ(1U, forms.size());
+ ASSERT_EQ(4U, forms[0]->field_count());
+
+ EXPECT_EQ(NAME_FIRST, forms[0]->field(0)->Type().GetStorableType());
+ EXPECT_EQ(NAME_LAST, forms[0]->field(1)->Type().GetStorableType());
+ EXPECT_EQ(test_params.required_type,
+ forms[0]->field(2)->Type().GetStorableType());
+
+ // Last field's type should have been overwritten to expected.
+ EXPECT_EQ(test_params.server_type,
+ forms[0]->field(3)->Type().GetStorableType());
+}
+
TEST_F(FormStructureTest, AllowBigForms) {
FormData form;
- form.origin = GURL("http://foo.com");
+ form.url = GURL("http://foo.com");
FormFieldData field;
// Check that the form with 250 fields are processed correctly.
for (size_t i = 0; i < 250; ++i) {
diff --git a/chromium/components/autofill/core/browser/label_formatter.cc b/chromium/components/autofill/core/browser/label_formatter.cc
index 32426dd7790..5fa3b42d195 100644
--- a/chromium/components/autofill/core/browser/label_formatter.cc
+++ b/chromium/components/autofill/core/browser/label_formatter.cc
@@ -4,14 +4,107 @@
#include "components/autofill/core/browser/label_formatter.h"
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+#include "components/autofill/core/browser/address_contact_form_label_formatter.h"
+#include "components/autofill/core/browser/address_email_form_label_formatter.h"
+#include "components/autofill/core/browser/address_form_label_formatter.h"
+#include "components/autofill/core/browser/address_phone_form_label_formatter.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/contact_form_label_formatter.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
+
namespace autofill {
+using data_util::bit_field_type_groups::kAddress;
+using data_util::bit_field_type_groups::kEmail;
+using data_util::bit_field_type_groups::kName;
+using data_util::bit_field_type_groups::kPhone;
+
LabelFormatter::LabelFormatter(const std::string& app_locale,
ServerFieldType focused_field_type,
+ uint32_t groups,
const std::vector<ServerFieldType>& field_types)
: app_locale_(app_locale),
focused_field_type_(focused_field_type),
- field_types_(field_types) {}
+ groups_(groups) {
+ const FieldTypeGroup focused_group = GetFocusedNonBillingGroup();
+ std::set<FieldTypeGroup> groups_for_labels{NAME, ADDRESS_HOME, EMAIL,
+ PHONE_HOME};
+
+ // If a user is focused on an address field, then parts of the address may be
+ // shown in the label. For example, if the user is focusing on a street
+ // address field, then it may be helpful to show the city in the label.
+ // Otherwise, the focused field should not appear in the label.
+ if (focused_group != ADDRESS_HOME) {
+ groups_for_labels.erase(focused_group);
+ }
+
+ // Countries are excluded to prevent them from appearing in labels with
+ // national addresses.
+ auto can_be_shown_in_label =
+ [&groups_for_labels](ServerFieldType type) -> bool {
+ return groups_for_labels.find(
+ AutofillType(AutofillType(type).GetStorableType()).group()) !=
+ groups_for_labels.end() &&
+ type != ADDRESS_HOME_COUNTRY && type != ADDRESS_BILLING_COUNTRY;
+ };
+
+ std::copy_if(field_types.begin(), field_types.end(),
+ std::back_inserter(field_types_for_labels_),
+ can_be_shown_in_label);
+}
+
LabelFormatter::~LabelFormatter() = default;
+std::vector<base::string16> LabelFormatter::GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const {
+ std::vector<base::string16> labels;
+ for (const AutofillProfile* profile : profiles) {
+ labels.push_back(GetLabelForProfile(*profile, GetFocusedNonBillingGroup()));
+ }
+ return labels;
+}
+
+FieldTypeGroup LabelFormatter::GetFocusedNonBillingGroup() const {
+ return AutofillType(AutofillType(focused_field_type_).GetStorableType())
+ .group();
+}
+
+// static
+std::unique_ptr<LabelFormatter> LabelFormatter::Create(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types,
+ const std::vector<AutofillProfile*>& profiles) {
+ const uint32_t groups = data_util::DetermineGroups(field_types);
+
+ switch (groups) {
+ case kName | kAddress | kEmail | kPhone:
+ return std::make_unique<AddressContactFormLabelFormatter>(
+ app_locale, focused_field_type, groups, field_types,
+ !HaveSamePhoneNumbers(profiles, app_locale),
+ !HaveSameEmailAddresses(profiles, app_locale));
+ case kName | kAddress | kPhone:
+ return std::make_unique<AddressPhoneFormLabelFormatter>(
+ app_locale, focused_field_type, groups, field_types);
+ case kName | kAddress | kEmail:
+ return std::make_unique<AddressEmailFormLabelFormatter>(
+ app_locale, focused_field_type, groups, field_types);
+ case kName | kAddress:
+ return std::make_unique<AddressFormLabelFormatter>(
+ app_locale, focused_field_type, groups, field_types);
+ case kName | kEmail | kPhone:
+ case kName | kEmail:
+ case kName | kPhone:
+ return std::make_unique<ContactFormLabelFormatter>(
+ app_locale, focused_field_type, groups, field_types);
+ default:
+ return nullptr;
+ }
+}
+
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter.h b/chromium/components/autofill/core/browser/label_formatter.h
index d436401044d..48172fcbff1 100644
--- a/chromium/components/autofill/core/browser/label_formatter.h
+++ b/chromium/components/autofill/core/browser/label_formatter.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_LABEL_FORMATTER_H_
+#include <memory>
#include <string>
#include <vector>
@@ -19,33 +20,67 @@ class LabelFormatter {
public:
LabelFormatter(const std::string& app_locale,
ServerFieldType focused_field_type,
+ uint32_t groups,
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;
+ // Returns the bitmask indicating which FieldTypeGroups are represented in
+ // this formatter's associated form.
+ uint32_t groups() const { return groups_; }
+
+ // Returns a collection of labels formed by extracting useful disambiguating
+ // information from a collection of |profiles_|.
+ std::vector<base::string16> GetLabels(
+ const std::vector<AutofillProfile*>& profiles) const;
+
+ // Creates a form-specific LabelFormatter according to |field_types|. This
+ // formatter has the ability to build labels with disambiguating information
+ // from the given |profiles|.
+ static std::unique_ptr<LabelFormatter> Create(
+ const std::string& app_locale,
+ ServerFieldType focused_field_type,
+ const std::vector<ServerFieldType>& field_types,
+ const std::vector<AutofillProfile*>& profiles);
protected:
+ // Returns a label to show the user. The elements of the label and their
+ // ordering depend on the kind of LabelFormatter, the data in |profile|,
+ // |focused_group|, and |focused_field_type_|.
+ virtual base::string16 GetLabelForProfile(
+ const AutofillProfile& profile,
+ FieldTypeGroup focused_group) const = 0;
+
+ // Returns the FieldTypeGroup with which |focused_field_type_| is associated.
+ // Billing field types are mapped to their corresponding home address field
+ // types. For example, if focused_field_type_ is ADDRESS_BILLING_ZIP, then
+ // the resulting FieldTypeGroup is ADDRESS_HOME instead of ADDRESS_BILLING.
+ FieldTypeGroup GetFocusedNonBillingGroup() const;
+
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_;
+
+ const std::vector<ServerFieldType>& field_types_for_labels() const {
+ return field_types_for_labels_;
}
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
+ // country for which the application is translated, e.g. en-AU for Australian
// English.
std::string app_locale_;
- // The field on which the user is currently focused.
+ // The type of field on which the user is focused, e.g. NAME_FIRST.
ServerFieldType focused_field_type_;
- // A collection of meaningful field types in the form with which the user is
- // interacting.
- std::vector<ServerFieldType> field_types_;
+ // The bitmask indicating which FieldTypeGroups are represented in this
+ // formatter's associated form.
+ uint32_t groups_;
+
+ // The collection of field types that can be used to make labels. It includes
+ // only types related to names, addresses, email addresses, and phone
+ // numbers. It excludes types related to countries.
+ std::vector<ServerFieldType> field_types_for_labels_;
};
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter_unittest.cc b/chromium/components/autofill/core/browser/label_formatter_unittest.cc
new file mode 100644
index 00000000000..fc66da066d7
--- /dev/null
+++ b/chromium/components/autofill/core/browser/label_formatter_unittest.cc
@@ -0,0 +1,24 @@
+// 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"
+
+#include <vector>
+
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+namespace {
+
+TEST(LabelFormatterTest, CreateWithMissingFieldTypes) {
+ EXPECT_EQ(LabelFormatter::Create("en-US", NAME_FIRST,
+ std::vector<ServerFieldType>(),
+ std::vector<AutofillProfile*>()),
+ nullptr);
+}
+
+} // namespace
+} // namespace autofill \ No newline at end of file
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils.cc b/chromium/components/autofill/core/browser/label_formatter_utils.cc
index 53d8eab8836..42bd1a109e6 100644
--- a/chromium/components/autofill/core/browser/label_formatter_utils.cc
+++ b/chromium/components/autofill/core/browser/label_formatter_utils.cc
@@ -4,112 +4,236 @@
#include "components/autofill/core/browser/label_formatter_utils.h"
+#include <algorithm>
+#include <iterator>
#include <memory>
-#include <set>
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/browser/address_form_label_formatter.h"
+#include "components/autofill/core/browser/address_i18n.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/phone_number_i18n.h"
#include "components/autofill/core/browser/validation.h"
+#include "components/grit/components_scaled_resources.h"
+#include "components/strings/grit/components_strings.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_formatter.h"
+#include "ui/base/l10n/l10n_util.h"
namespace autofill {
-namespace {
-bool ContainsName(uint32_t groups) {
- return groups & label_formatter_groups::kName;
+const int kStreetAddressFieldTypes[] = {
+ ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2,
+ ADDRESS_HOME_APT_NUM, ADDRESS_BILLING_LINE1,
+ ADDRESS_BILLING_LINE2, ADDRESS_BILLING_APT_NUM,
+ ADDRESS_HOME_STREET_ADDRESS, ADDRESS_BILLING_STREET_ADDRESS,
+ ADDRESS_HOME_LINE3, ADDRESS_BILLING_LINE3};
+
+bool IsStreetAddressPart(ServerFieldType type) {
+ return std::find(std::begin(kStreetAddressFieldTypes),
+ std::end(kStreetAddressFieldTypes),
+ type) != std::end(kStreetAddressFieldTypes);
}
-bool ContainsAddress(uint32_t groups) {
- return groups & label_formatter_groups::kAddress;
+bool HasStreetAddress(const std::vector<ServerFieldType>& types) {
+ return std::any_of(types.begin(), types.end(), IsStreetAddressPart);
}
-bool ContainsEmail(uint32_t groups) {
- return groups & label_formatter_groups::kEmail;
+std::vector<ServerFieldType> ExtractSpecifiedAddressFieldTypes(
+ bool extract_street_address_types,
+ const std::vector<ServerFieldType>& types) {
+ auto should_be_extracted =
+ [&extract_street_address_types](ServerFieldType type) -> bool {
+ return AutofillType(AutofillType(type).GetStorableType()).group() ==
+ ADDRESS_HOME &&
+ (extract_street_address_types ? IsStreetAddressPart(type)
+ : !IsStreetAddressPart(type));
+ };
+
+ std::vector<ServerFieldType> extracted_address_types;
+ std::copy_if(types.begin(), types.end(),
+ std::back_inserter(extracted_address_types),
+ should_be_extracted);
+
+ return extracted_address_types;
}
-bool ContainsPhone(uint32_t groups) {
- return groups & label_formatter_groups::kPhone;
+std::vector<ServerFieldType> ExtractAddressFieldTypes(
+ const std::vector<ServerFieldType>& types) {
+ std::vector<ServerFieldType> only_address_types;
+
+ // Note that GetStorableType maps billing fields to their corresponding non-
+ // billing fields, e.g. ADDRESS_HOME_ZIP is mapped to ADDRESS_BILLING_ZIP.
+ std::copy_if(
+ types.begin(), types.end(), std::back_inserter(only_address_types),
+ [](ServerFieldType type) {
+ return AutofillType(AutofillType(type).GetStorableType()).group() ==
+ ADDRESS_HOME;
+ });
+ return only_address_types;
}
-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);
+void AddLabelPartIfNotEmpty(const base::string16& part,
+ std::vector<base::string16>* parts) {
+ if (!part.empty()) {
+ parts->push_back(part);
}
- if (ContainsPhone(groups)) {
- field_type_groups.insert(PHONE_HOME);
- }
- return field_type_groups;
}
-} // namespace
+base::string16 ConstructLabelLine(const std::vector<base::string16>& parts) {
+ return base::JoinString(parts, l10n_util::GetStringUTF16(
+ IDS_AUTOFILL_SUGGESTION_LABEL_SEPARATOR));
+}
-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;
- }
+AutofillProfile MakeTrimmedProfile(const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types) {
+ AutofillProfile trimmed_profile(profile.guid(), profile.origin());
+ trimmed_profile.set_language_code(profile.language_code());
+
+ const AutofillType country_code_type(HTML_TYPE_COUNTRY_CODE, HTML_MODE_NONE);
+ const base::string16 country_code =
+ profile.GetInfo(country_code_type, app_locale);
+ trimmed_profile.SetInfo(country_code_type, country_code, app_locale);
+
+ for (const ServerFieldType& type : types) {
+ trimmed_profile.SetInfo(type, profile.GetInfo(type, app_locale),
+ app_locale);
}
- return group_bitmask;
+ return trimmed_profile;
}
-std::unique_ptr<LabelFormatter> Create(
- const std::string& app_locale,
+base::string16 GetLabelName(const AutofillProfile& profile,
+ const std::string& app_locale) {
+ return profile.GetInfo(AutofillType(NAME_FULL), app_locale);
+}
+
+base::string16 GetLabelForFocusedAddress(
ServerFieldType focused_field_type,
- const std::vector<ServerFieldType>& field_types) {
- const uint32_t groups = DetermineGroups(field_types);
+ bool form_has_street_address,
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types) {
+ return GetLabelAddress(
+ form_has_street_address && !IsStreetAddressPart(focused_field_type),
+ profile, app_locale, 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));
+base::string16 GetLabelAddress(bool use_street_address,
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types) {
+ return use_street_address
+ ? GetLabelStreetAddress(
+ profile, app_locale,
+ ExtractSpecifiedAddressFieldTypes(use_street_address, types))
+ : GetLabelNationalAddress(profile, app_locale,
+ ExtractSpecifiedAddressFieldTypes(
+ use_street_address, types));
+}
+
+base::string16 GetLabelNationalAddress(
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types) {
+ std::unique_ptr<::i18n::addressinput::AddressData> address_data =
+ i18n::CreateAddressDataFromAutofillProfile(
+ MakeTrimmedProfile(profile, app_locale, types), app_locale);
+
+ std::string address_line;
+ ::i18n::addressinput::GetFormattedNationalAddressLine(*address_data,
+ &address_line);
+ return base::UTF8ToUTF16(address_line);
+}
+
+base::string16 GetLabelStreetAddress(
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types) {
+ std::unique_ptr<::i18n::addressinput::AddressData> address_data =
+ i18n::CreateAddressDataFromAutofillProfile(
+ MakeTrimmedProfile(profile, app_locale, types), app_locale);
+
+ std::string address_line;
+ ::i18n::addressinput::GetStreetAddressLinesAsSingleLine(*address_data,
+ &address_line);
+ return base::UTF8ToUTF16(address_line);
+}
+
+base::string16 GetLabelForProfileOnFocusedNonStreetAddress(
+ bool form_has_street_address,
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types,
+ const base::string16& contact_info) {
+ std::vector<base::string16> label_parts;
+ AddLabelPartIfNotEmpty(
+ GetLabelAddress(form_has_street_address, profile, app_locale, types),
+ &label_parts);
+ AddLabelPartIfNotEmpty(contact_info, &label_parts);
+ return ConstructLabelLine(label_parts);
+}
+
+base::string16 GetLabelEmail(const AutofillProfile& profile,
+ const std::string& app_locale) {
+ const base::string16 email =
+ profile.GetInfo(AutofillType(EMAIL_ADDRESS), app_locale);
+ return IsValidEmailAddress(email) ? email : base::string16();
+}
+
+base::string16 GetLabelPhone(const AutofillProfile& profile,
+ const std::string& app_locale) {
+ const std::string unformatted_phone = base::UTF16ToUTF8(
+ profile.GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), app_locale));
+ return unformatted_phone.empty()
+ ? base::string16()
+ : base::UTF8ToUTF16(i18n::FormatPhoneNationallyForDisplay(
+ unformatted_phone,
+ data_util::GetCountryCodeWithFallback(profile, app_locale)));
+}
+
+bool HaveSameEmailAddresses(const std::vector<AutofillProfile*>& profiles,
+ const std::string& app_locale) {
+ bool first_email_found = false;
+ base::string16 first_email;
+
+ for (const AutofillProfile* profile : profiles) {
+ base::string16 email_from_profile = GetLabelEmail(*profile, app_locale);
+
+ if (!first_email_found) {
+ // Store the first email address whether it's empty or not because we
+ // consider "" and "hao.le@aol.com" to be different email addresses.
+ first_email_found = true;
+ first_email = email_from_profile;
+ } else if (email_from_profile != first_email) {
+ return false;
+ }
}
- if (ContainsEmail(groups) || ContainsPhone(groups)) {
- return std::make_unique<ContactFormLabelFormatter>(
- app_locale, focused_field_type, FilterFieldTypes(field_types),
- GetFieldTypeGroups(groups));
+ return true;
+}
+
+bool HaveSamePhoneNumbers(const std::vector<AutofillProfile*>& profiles,
+ const std::string& app_locale) {
+ bool first_phone_found = false;
+ base::string16 first_phone;
+
+ for (const AutofillProfile* profile : profiles) {
+ base::string16 phone_from_profile = GetLabelPhone(*profile, app_locale);
+
+ if (!first_phone_found) {
+ // Store the first phone number whether it's empty or not because we
+ // consider "" and "(514) 873-1100" to be different phone numbers.
+ first_phone_found = true;
+ first_phone = phone_from_profile;
+ } else if (!(first_phone.empty() && phone_from_profile.empty()) &&
+ !i18n::PhoneNumbersMatch(first_phone, phone_from_profile,
+ base::UTF16ToASCII(profile->GetInfo(
+ ADDRESS_HOME_COUNTRY, app_locale)),
+ app_locale)) {
+ return false;
+ }
}
- return nullptr;
+ return true;
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils.h b/chromium/components/autofill/core/browser/label_formatter_utils.h
index 80b21942c39..c12d58958d7 100644
--- a/chromium/components/autofill/core/browser/label_formatter_utils.h
+++ b/chromium/components/autofill/core/browser/label_formatter_utils.h
@@ -5,53 +5,146 @@
#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 "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 {
-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 true if kName is set in |groups|.
+bool ContainsName(uint32_t groups);
+
+// Returns true if kAddress is set in |groups|.
+bool ContainsAddress(uint32_t groups);
+
+// Returns true if kEmail is set in |groups|.
+bool ContainsEmail(uint32_t groups);
+
+// Returns true if kPhone is set in |groups|.
+bool ContainsPhone(uint32_t groups);
// 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);
+uint32_t DetermineGroups(const std::vector<ServerFieldType>& 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,
+// Returns true if |type| is a component of a street address.
+bool IsStreetAddressPart(ServerFieldType type);
+
+// Returns true if |types| has a street-address-related field.
+bool HasStreetAddress(const std::vector<ServerFieldType>& types);
+
+// Returns a vector of only street-address-related field types in |types| if
+// |extract_street_address_types| is true, e.g. ADDRESS_HOME_LINE1.
+//
+// Returns a vector of only non-street-address-related field types in |types|
+// if |extract_street_address_types| is false, e.g. ADDRESS_BILLING_ZIP.
+std::vector<ServerFieldType> ExtractSpecifiedAddressFieldTypes(
+ bool extract_street_address_types,
+ const std::vector<ServerFieldType>& types);
+
+// Returns a collection of the types in |types| that belong to the
+// ADDRESS_HOME or ADDRESS_BILLING FieldTypeGroups.
+std::vector<ServerFieldType> ExtractAddressFieldTypes(
+ const std::vector<ServerFieldType>& types);
+
+// Adds |part| to |parts| if |part| is not an empty string.
+void AddLabelPartIfNotEmpty(const base::string16& part,
+ std::vector<base::string16>* parts);
+
+// Returns the text to show to the user. If there is more than one element in
+// |parts|, then a separator, |IDS_AUTOFILL_SUGGESTION_LABEL_SEPARATOR|, is
+// inserted between them.
+base::string16 ConstructLabelLine(const std::vector<base::string16>& parts);
+
+// Returns a pared down copy of |profile|. The copy has the same guid, origin,
+// country and language codes, and |field_types| as |profile|.
+AutofillProfile MakeTrimmedProfile(const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types);
+
+// Returns the full name associated with |profile|.
+base::string16 GetLabelName(const AutofillProfile& profile,
+ const std::string& app_locale);
+
+// Returns either street-address data or non-street-address data found in
+// |profile|. If |focused_field_type| is a street address field, then returns
+// non-street-address data, e.g. Lowell, MA 01852.
+//
+// If the focused type is not a street address field and if
+// |form_has_street_address| is true, then returns street-address data, e.g. 375
+// Merrimack St.
+//
+// If the focused type is not a street address field and if the form does not
+// have a street address, then returns the parts of the address in the form
+// other than the focused field. For example, if a user focuses on a city
+// field and if the state and zip code can be in the label, then MA 01852 is
+// returned. If there are no other non-street-address fields or if the data is
+// not present in |profile|, then an empty string is returned.
+base::string16 GetLabelForFocusedAddress(
ServerFieldType focused_field_type,
- const std::vector<ServerFieldType>& field_types);
+ bool form_has_street_address,
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types);
+
+// If |form_has_street_address_| is true and if |profile| is associated with a
+// street address, then returns the street address, e.g. 24 Beacon St.
+//
+// If |form_has_street_address_| is false and |profile| is associated with
+// address fields other than street addresses, then returns the non-street-
+// address-related data corresponding to |types|.
+base::string16 GetLabelAddress(bool use_street_address,
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types);
+
+// Returns the national address associated with |profile|, e.g.
+// 24 Beacon St., Boston, MA 02133.
+base::string16 GetLabelNationalAddress(
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types);
+
+// Returns the street address associated with |profile|, e.g. 24 Beacon St.
+base::string16 GetLabelStreetAddress(const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types);
+
+// Returns a label to show the user when |focused_field_type_| is not part of
+// a street address. For example, city and postal code are non-street-address
+// field types.
+base::string16 GetLabelForProfileOnFocusedNonStreetAddress(
+ bool form_has_street_address,
+ const AutofillProfile& profile,
+ const std::string& app_locale,
+ const std::vector<ServerFieldType>& types,
+ const base::string16& contact_info);
+
+// Returns the email address associated with |profile|, if any; otherwise,
+// returns an empty string.
+base::string16 GetLabelEmail(const AutofillProfile& profile,
+ const std::string& app_locale);
+
+// Returns the phone number associated with |profile|, if any; otherwise,
+// returns an empty string. Phone numbers are given in |profile|'s country's
+// national format, if possible.
+base::string16 GetLabelPhone(const AutofillProfile& profile,
+ const std::string& app_locale);
+
+// Returns true if all |profiles| have the same email address. Note that the
+// absence of an email address and an actual email address, e.g.
+// joe.bray@aol.com, are considered different email addresses.
+bool HaveSameEmailAddresses(const std::vector<AutofillProfile*>& profiles,
+ const std::string& app_locale);
+
+// Returns true if all |profiles| have the same phone number after
+// normalization. Note that the absence of a phone number and an actual phone
+// number, e.g. (401) 847-8720, are considered different phone numbers.
+bool HaveSamePhoneNumbers(const std::vector<AutofillProfile*>& profiles,
+ const std::string& app_locale);
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc b/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc
index 660cb0263d3..237ec3c5f36 100644
--- a/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc
+++ b/chromium/components/autofill/core/browser/label_formatter_utils_unittest.cc
@@ -4,43 +4,25 @@
#include "components/autofill/core/browser/label_formatter_utils.h"
+#include "base/guid.h"
+#include "base/strings/string16.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"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/grit/components_scaled_resources.h"
+#include "components/strings/grit/components_strings.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.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);
-}
+using data_util::bit_field_type_groups::kAddress;
+using data_util::bit_field_type_groups::kEmail;
+using data_util::bit_field_type_groups::kName;
+using data_util::bit_field_type_groups::kPhone;
TEST(LabelFormatterUtilsTest, DetermineGroupsForHomeNameAndAddress) {
const std::vector<ServerFieldType> field_types{
@@ -48,7 +30,7 @@ TEST(LabelFormatterUtilsTest, DetermineGroupsForHomeNameAndAddress) {
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);
+ const uint32_t group_bitmask = data_util::DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
@@ -58,7 +40,7 @@ TEST(LabelFormatterUtilsTest, DetermineGroupsForBillingNameAndAddress) {
ADDRESS_BILLING_STATE, ADDRESS_BILLING_ZIP};
const uint32_t expected_group_bitmask = kName | kAddress;
- const uint32_t group_bitmask = DetermineGroups(field_types);
+ const uint32_t group_bitmask = data_util::DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
@@ -67,7 +49,7 @@ TEST(LabelFormatterUtilsTest, DetermineGroupsForHomeNamePhoneAndEmail) {
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);
+ const uint32_t group_bitmask = data_util::DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
@@ -76,7 +58,7 @@ TEST(LabelFormatterUtilsTest, DetermineGroupsForBillingNamePhoneAndEmail) {
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);
+ const uint32_t group_bitmask = data_util::DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
@@ -85,7 +67,7 @@ TEST(LabelFormatterUtilsTest, DetermineGroupsForUnknownServerFieldType) {
ADDRESS_HOME_ZIP};
const uint32_t expected_group_bitmask = kName | kAddress;
- const uint32_t group_bitmask = DetermineGroups(field_types);
+ const uint32_t group_bitmask = data_util::DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
@@ -93,8 +75,171 @@ 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);
+ const uint32_t group_bitmask = data_util::DetermineGroups(field_types);
EXPECT_EQ(expected_group_bitmask, group_bitmask);
}
-} // namespace autofill \ No newline at end of file
+TEST(LabelFormatterUtilsTest, ConstructLabelLine) {
+ EXPECT_EQ(base::string16(), ConstructLabelLine({}));
+
+ base::string16 name = base::ASCIIToUTF16("Blaise Pascal");
+ base::string16 phone = base::ASCIIToUTF16("01 53 01 82 00");
+ base::string16 email = base::ASCIIToUTF16("b.pascal@orange.fr");
+
+ base::string16 separator =
+ l10n_util::GetStringUTF16(IDS_AUTOFILL_SUGGESTION_LABEL_SEPARATOR);
+
+ EXPECT_EQ(name, ConstructLabelLine({name}));
+ EXPECT_EQ(base::JoinString({name, separator, phone, separator, email},
+ base::string16()),
+ ConstructLabelLine({name, phone, email}));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSameEmailAddressesWithOneProfileAndNoEmailAddress) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Maria", "Margaretha", "Kirch",
+ "mmkirch@gmx.de", "", "", "", "", "", "", "DE", "");
+ EXPECT_TRUE(HaveSameEmailAddresses({&profile}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSameEmailAddressesWithOneProfileAndEmailAddress) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Maria", "Margaretha", "Kirch", "", "", "", "",
+ "", "", "", "DE", "");
+ EXPECT_TRUE(HaveSameEmailAddresses({&profile}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSameEmailAddressesWithProfilesAndNoEmailAddresses) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch", "", "", "",
+ "", "", "", "", "DE", "");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann", "", "",
+ "", "", "", "", "", "DE", "");
+ EXPECT_TRUE(HaveSameEmailAddresses({&profile1, &profile2}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSameEmailAddressesWithProfilesAndSameEmailAddresses) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch",
+ "mmkirch@gmx.de", "", "", "", "", "", "", "DE", "");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann",
+ "mmkirch@gmx.de", "", "", "", "", "", "", "DE", "");
+ EXPECT_TRUE(HaveSameEmailAddresses({&profile1, &profile2}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSameEmailAddressesWithProfilesAndDifferentNonEmptyEmailAddresses) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch",
+ "mmkirch@gmx.de", "", "", "", "", "", "", "DE", "");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann",
+ "mmw@gmail.com", "", "", "", "", "", "", "DE", "");
+ EXPECT_FALSE(HaveSameEmailAddresses({&profile1, &profile2}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSameEmailAddressesWithProfilesAndNonEmptyAndEmptyEmailAddresses) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch",
+ "mmkirch@gmx.de", "", "", "", "", "", "", "DE", "");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann", "", "",
+ "", "", "", "", "", "DE", "");
+ EXPECT_FALSE(HaveSameEmailAddresses({&profile1, &profile2}, "de"));
+ EXPECT_FALSE(HaveSameEmailAddresses({&profile2, &profile1}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSamePhoneNumbersWithOneProfileAndNoPhoneNumber) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Maria", "Margaretha", "Kirch", "", "", "", "",
+ "", "", "", "DE", "");
+ EXPECT_TRUE(HaveSamePhoneNumbers({&profile}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSamePhoneNumbersWithOneProfileAndPhoneNumber) {
+ AutofillProfile profile =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Maria", "Margaretha", "Kirch", "", "", "", "",
+ "", "", "", "DE", "+49 30 4504-2823");
+ EXPECT_TRUE(HaveSamePhoneNumbers({&profile}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSamePhoneNumbersWithProfilesAndNoPhoneNumber) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch", "", "", "",
+ "", "", "", "", "DE", "");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann", "", "",
+ "", "", "", "", "", "DE", "");
+ EXPECT_TRUE(HaveSamePhoneNumbers({&profile1, &profile2}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSamePhoneNumbersWithProfilesAndSamePhoneNumbers) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch", "", "", "",
+ "", "", "", "", "DE", "+49 30 4504-2823");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann", "", "",
+ "", "", "", "", "", "DE", "4903045042823");
+ AutofillProfile profile3 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile3, "Maria", "Margaretha", "Winckelmann", "", "",
+ "", "", "", "", "", "DE", "03045042823");
+ EXPECT_TRUE(HaveSamePhoneNumbers({&profile1, &profile2, &profile3}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSamePhoneNumbersWithProfilesAndDifferentNonEmptyPhoneNumbers) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch", "", "", "",
+ "", "", "", "", "DE", "+49 30 4504-2823");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann", "", "",
+ "", "", "", "", "", "DE", "+49 221 22123828");
+ EXPECT_FALSE(HaveSamePhoneNumbers({&profile1, &profile2}, "de"));
+}
+
+TEST(LabelFormatterUtilsTest,
+ HaveSamePhoneNumbersWithProfilesAndNonEmptyAndEmptyPhoneNumbers) {
+ AutofillProfile profile1 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Maria", "Margaretha", "Kirch", "", "", "",
+ "", "", "", "", "DE", "+49 30 4504-2823");
+ AutofillProfile profile2 =
+ AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Maria", "Margaretha", "Winckelmann", "", "",
+ "", "", "", "", "", "DE", "");
+ EXPECT_FALSE(HaveSamePhoneNumbers({&profile1, &profile2}, "de"));
+ EXPECT_FALSE(HaveSamePhoneNumbers({&profile2, &profile1}, "de"));
+}
+
+} // namespace
+} // 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
index 06674d12c2d..129918d6774 100644
--- a/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc
+++ b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.cc
@@ -4,14 +4,47 @@
#include "components/autofill/core/browser/metrics/address_form_event_logger.h"
+#include <algorithm>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+#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_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"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/autofill_type.h"
+#include "components/autofill/core/browser/field_types.h"
namespace autofill {
+namespace {
+
+using data_util::bit_field_type_groups::kAddress;
+using data_util::bit_field_type_groups::kEmail;
+using data_util::bit_field_type_groups::kName;
+using data_util::bit_field_type_groups::kPhone;
+
+// Returns the histogram suffix corresponding to the given |bitmask|.
+std::string GetSuffixForFormType(uint32_t bitmask) {
+ switch (bitmask) {
+ case kName | kAddress | kEmail | kPhone:
+ return ".AddressPlusEmailPlusPhone";
+ case kName | kAddress | kPhone:
+ return ".AddressPlusPhone";
+ case kName | kAddress | kEmail:
+ return ".AddressPlusEmail";
+ case kName | kAddress:
+ return ".AddressOnly";
+ case kName | kEmail | kPhone:
+ case kName | kEmail:
+ case kName | kPhone:
+ return ".ContactOnly";
+ default:
+ return ".Other";
+ }
+}
+
+} // namespace
AddressFormEventLogger::AddressFormEventLogger(
bool is_in_main_frame,
@@ -74,6 +107,26 @@ void AddressFormEventLogger::OnSubsequentRefillAttempt(
Log(FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, form);
}
+void AddressFormEventLogger::OnLog(const std::string& name,
+ FormEvent event,
+ const FormStructure& form) const {
+ std::vector<ServerFieldType> types;
+ std::transform(
+ form.begin(), form.end(), std::back_inserter(types),
+ [&](const std::unique_ptr<AutofillField>& field) -> ServerFieldType {
+ return field->Type().GetStorableType();
+ });
+
+ uint32_t groups = data_util::DetermineGroups(types);
+ base::UmaHistogramEnumeration(name + GetSuffixForFormType(groups), event,
+ NUM_FORM_EVENTS);
+ if (data_util::ContainsName(groups) && data_util::ContainsAddress(groups) &&
+ (data_util::ContainsPhone(groups) || data_util::ContainsEmail(groups))) {
+ base::UmaHistogramEnumeration(name + ".AddressPlusContact", event,
+ NUM_FORM_EVENTS);
+ }
+}
+
void AddressFormEventLogger::RecordPollSuggestions() {
base::RecordAction(
base::UserMetricsAction("Autofill_PolledProfileSuggestions"));
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
index a115ffbde83..52d467dca02 100644
--- a/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h
+++ b/chromium/components/autofill/core/browser/metrics/address_form_event_logger.h
@@ -5,10 +5,15 @@
#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 <string>
+
+#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/form_structure.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/sync_utils.h"
namespace autofill {
@@ -38,6 +43,9 @@ class AddressFormEventLogger : public FormEventLoggerBase {
void RecordPollSuggestions() override;
void RecordParseForm() override;
void RecordShowSuggestions() override;
+ void OnLog(const std::string& name,
+ FormEvent event,
+ const FormStructure& form) const override;
};
} // namespace autofill
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
index ea19e7317b9..03aea4fe00c 100644
--- 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
@@ -9,13 +9,8 @@
#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 "base/strings/string16.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 {
@@ -155,7 +150,8 @@ void CreditCardFormEventLogger::OnSuggestionsShownSubmittedOnce(
}
void CreditCardFormEventLogger::OnLog(const std::string& name,
- FormEvent event) const {
+ FormEvent event,
+ const FormStructure& form) 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_) {
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
index 67a16324dae..05c64a9fca2 100644
--- 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
@@ -8,12 +8,15 @@
#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_field.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_structure.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"
+#include "components/autofill/core/browser/sync_utils.h"
+#include "components/autofill/core/common/signatures_util.h"
namespace autofill {
@@ -67,7 +70,9 @@ class CreditCardFormEventLogger : public FormEventLoggerBase {
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;
+ void OnLog(const std::string& name,
+ FormEvent event,
+ const FormStructure& form) const override;
// Bringing base class' Log function into scope to allow overloading.
using FormEventLoggerBase::Log;
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
index 99025b5070b..7a7edfcf177 100644
--- a/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc
+++ b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.cc
@@ -4,22 +4,10 @@
#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 {
@@ -151,8 +139,8 @@ void FormEventLoggerBase::Log(FormEvent event,
name + (is_in_main_frame_ ? ".IsInMainFrame" : ".IsInIFrame"), event,
NUM_FORM_EVENTS);
- // Allow specialized type of logging.
- OnLog(name, event);
+ // Allow specialized types of logging, e.g. splitting metrics in useful ways.
+ OnLog(name, event, form);
// Logging again in a different histogram for segmentation purposes.
if (server_record_type_count_ == 0 && local_record_type_count_ == 0)
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
index 173df3b0ddd..f07e69504db 100644
--- a/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h
+++ b/chromium/components/autofill/core/browser/metrics/form_event_logger_base.h
@@ -7,15 +7,13 @@
#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"
+#include "components/autofill/core/common/signatures_util.h"
namespace autofill {
@@ -77,7 +75,14 @@ class FormEventLoggerBase {
virtual void OnSuggestionsShownOnce() {}
virtual void OnSuggestionsShownSubmittedOnce(const FormStructure& form) {}
- virtual void OnLog(const std::string& name, FormEvent event) const {}
+
+ // Logs |event| in a histogram prefixed with |name| according to the
+ // FormEventLogger type and |form|. For example, in the address context, it
+ // may be useful to analyze metrics for forms (A) with only name and address
+ // fields and (B) with only name and phone fields separately.
+ virtual void OnLog(const std::string& name,
+ FormEvent event,
+ const FormStructure& form) const {}
// Constructor parameters.
std::string form_type_name_;
diff --git a/chromium/components/autofill/core/browser/password_generator.cc b/chromium/components/autofill/core/browser/password_generator.cc
deleted file mode 100644
index 99101938f7a..00000000000
--- a/chromium/components/autofill/core/browser/password_generator.cc
+++ /dev/null
@@ -1,222 +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/password_generator.h"
-
-#include <algorithm>
-#include <limits>
-#include <map>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/rand_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/browser/proto/password_requirements.pb.h"
-
-namespace autofill {
-
-// The default length for a generated password. Keep this the same as the
-// default length known to the classification pipeline on the autofill
-// crowd-sourcing server. (The server predicts password lengths only if the
-// prediction is smaller than the default.)
-const uint32_t kDefaultPasswordLength = 15;
-
-namespace {
-
-// Default character sets used if the spec does not override the character set.
-// Removed characters due to visual similarity:
-// - l (lowercase L)
-// - I (capital i)
-// - 1 (one)
-// - O (capital o)
-// - 0 (zero)
-// - o (lowercase O)
-constexpr char kLowerCaseChars[] = "abcdefghijkmnpqrstuvwxyz";
-constexpr char kUpperCaseChars[] = "ABCDEFGHJKLMNPQRSTUVWXYZ";
-constexpr char kAlphabeticChars[] =
- "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
-constexpr char kDigits[] = "23456789";
-constexpr char kSymbols[] = "-_.:!";
-
-// Returns a default password requirements specification that requires:
-// - at least one lower case letter
-// - at least one upper case letter
-// - at least one number
-// - no symbols
-PasswordRequirementsSpec BuildDefaultSpec() {
- // Note the the fields below should be initialized in the order of their
- // proto field numbers to reduce the risk of forgetting a field.
- PasswordRequirementsSpec spec;
- spec.set_priority(0);
- spec.set_spec_version(1);
- // spec.min_length and spec.max_length remain unset to fall back to
- // PasswordGenerator::kDefaultPasswordLength.
-
- spec.mutable_lower_case()->set_character_set(kLowerCaseChars);
- spec.mutable_lower_case()->set_min(1);
- spec.mutable_lower_case()->set_max(std::numeric_limits<int32_t>::max());
-
- spec.mutable_upper_case()->set_character_set(kUpperCaseChars);
- spec.mutable_upper_case()->set_min(1);
- spec.mutable_upper_case()->set_max(std::numeric_limits<int32_t>::max());
-
- spec.mutable_alphabetic()->set_character_set(kAlphabeticChars);
- spec.mutable_alphabetic()->set_min(0);
- spec.mutable_alphabetic()->set_max(0);
-
- spec.mutable_numeric()->set_character_set(kDigits);
- spec.mutable_numeric()->set_min(1);
- spec.mutable_numeric()->set_max(std::numeric_limits<int32_t>::max());
-
- spec.mutable_symbols()->set_character_set(kSymbols);
- spec.mutable_symbols()->set_min(0);
- spec.mutable_symbols()->set_max(0);
- return spec;
-}
-
-// Returns whether the password is difficult to read because it contains
-// sequences of '-' or '_' that are joined into long strokes on the screen
-// in many fonts.
-bool IsDifficultToRead(const base::string16& password) {
- return std::adjacent_find(password.begin(), password.end(),
- [](auto a, auto b) {
- return a == b && (a == '-' || a == '_');
- }) != password.end();
-}
-
-// Generates a password according to |spec| and tries to maximze the entropy
-// while not caring for pronounceable passwords.
-//
-// |spec| must contain values for at least all fields that are defined
-// in the spec of BuildDefaultSpec().
-base::string16 GenerateMaxEntropyPassword(PasswordRequirementsSpec spec) {
- using CharacterClass = PasswordRequirementsSpec_CharacterClass;
-
- // Determine target length.
- uint32_t target_length = kDefaultPasswordLength;
- if (spec.has_min_length())
- target_length = std::max(target_length, spec.min_length());
- if (spec.has_max_length())
- target_length = std::min(target_length, spec.max_length());
- // Avoid excessively long passwords.
- target_length = std::min(target_length, 200u);
-
- // The password that is being generated in this function.
- base::string16 password;
- password.reserve(target_length);
-
- // A list of CharacterClasses that have not been fully used.
- std::vector<CharacterClass*> classes;
- // The list of allowed characters in a specific class. This map exists
- // to calculate the string16 conversion only once.
- std::map<CharacterClass*, base::string16> characters_of_class;
-
- // These are guaranteed to exist because |spec| is an overlay of the default
- // spec.
- DCHECK(spec.has_lower_case());
- DCHECK(spec.has_upper_case());
- DCHECK(spec.has_alphabetic());
- DCHECK(spec.has_numeric());
- DCHECK(spec.has_symbols());
-
- // Initialize |classes| and |characters_of_class| and sanitize |spec|
- // if necessary.
- for (CharacterClass* character_class :
- {spec.mutable_lower_case(), spec.mutable_upper_case(),
- spec.mutable_alphabetic(), spec.mutable_numeric(),
- spec.mutable_symbols()}) {
- DCHECK(character_class->has_character_set());
- DCHECK(character_class->has_min());
- DCHECK(character_class->has_max());
-
- // If the character set is empty, we cannot generate characters from it.
- if (character_class->character_set().empty())
- character_class->set_max(0);
-
- // The the maximum is smaller than the minimum, limit the minimum.
- if (character_class->max() < character_class->min())
- character_class->set_min(character_class->max());
-
- if (character_class->max() > 0) {
- classes.push_back(character_class);
- characters_of_class[character_class] =
- base::UTF8ToUTF16(character_class->character_set());
- }
- }
-
- // Generate a password that contains the minimum number of characters of the
- // various character classes as per requirements. This stops when the target
- // length is achieved. Note that this is just a graceful handling of a buggy
- // spec. It should not happen that more characters are needed than can
- // accommodated.
- for (CharacterClass* character_class : classes) {
- while (character_class->min() > 0 && password.length() < target_length) {
- const base::string16& possible_chars =
- characters_of_class[character_class];
- password += possible_chars[base::RandGenerator(possible_chars.length())];
- character_class->set_min(character_class->min() - 1);
- character_class->set_max(character_class->max() - 1);
- }
- }
-
- // Now fill the rest of the password with random characters.
- while (password.length() < target_length) {
- // Determine how many different characters are in all remaining character
- // classes.
- size_t number_of_possible_chars = 0;
- for (CharacterClass* character_class : classes) {
- if (character_class->max() > 0) {
- number_of_possible_chars +=
- characters_of_class[character_class].length();
- }
- }
- if (number_of_possible_chars == 0)
- break;
- uint64_t choice = base::RandGenerator(number_of_possible_chars);
- // Now figure out which character was chosen and append it.
- for (CharacterClass* character_class : classes) {
- if (character_class->max() > 0) {
- size_t size_of_class = characters_of_class[character_class].length();
- if (choice < size_of_class) {
- password += characters_of_class[character_class][choice];
- character_class->set_max(character_class->max() - 1);
- break;
- } else {
- choice -= size_of_class;
- }
- }
- }
- }
-
- // So far the password contains the minimally required characters at the
- // the beginning. Therefore, we create a random permutation.
- // TODO(crbug.com/847200): Once the unittests allow controlling the generated
- // string, test that '--' and '__' are eliminated.
- int remaining_attempts = 5;
- do {
- base::RandomShuffle(password.begin(), password.end());
- } while (IsDifficultToRead(password) && remaining_attempts-- > 0);
-
- return password;
-}
-
-} // namespace
-
-base::string16 GeneratePassword(const PasswordRequirementsSpec& spec) {
- PasswordRequirementsSpec actual_spec = BuildDefaultSpec();
-
- // Override all fields that are set in |spec|. Character classes are merged
- // recursively.
- actual_spec.MergeFrom(spec);
-
- base::string16 password = GenerateMaxEntropyPassword(std::move(actual_spec));
-
- // Catch cases where supplied spec is infeasible.
- if (password.empty())
- password = GenerateMaxEntropyPassword(BuildDefaultSpec());
-
- return password;
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_generator.h b/chromium/components/autofill/core/browser/password_generator.h
deleted file mode 100644
index 4ff870f942d..00000000000
--- a/chromium/components/autofill/core/browser/password_generator.h
+++ /dev/null
@@ -1,30 +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.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_H_
-
-#include "base/strings/string16.h"
-
-namespace autofill {
-
-class PasswordRequirementsSpec;
-
-extern const uint32_t kDefaultPasswordLength;
-
-// Returns a password that follows the |spec| as well as possible. If this is
-// impossible, a password that nearly meets the requirements can be returned.
-// In this case the user is asked to fix the password themselves.
-//
-// If |spec| is empty, a password of length |kDefaultPasswordLength| is
-// generated that contains
-// - at least 1 lower case latin character
-// - at least 1 upper case latin character
-// - at least 1 number (digit)
-// - no symbols
-base::string16 GeneratePassword(const PasswordRequirementsSpec& spec);
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_H_
diff --git a/chromium/components/autofill/core/browser/password_generator_fips181.cc b/chromium/components/autofill/core/browser/password_generator_fips181.cc
deleted file mode 100644
index 3226576ea9b..00000000000
--- a/chromium/components/autofill/core/browser/password_generator_fips181.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2013 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/password_generator_fips181.h"
-
-#include <stddef.h>
-
-#include <algorithm>
-#include <vector>
-
-#include "base/rand_util.h"
-#include "base/strings/string_util.h"
-#include "third_party/fips181/fips181.h"
-
-namespace {
-
-const int kMinUpper = 65; // First upper case letter 'A'
-const int kMaxUpper = 90; // Last upper case letter 'Z'
-const int kMinLower = 97; // First lower case letter 'a'
-const int kMaxLower = 122; // Last lower case letter 'z'
-const int kMinDigit = 48; // First digit '0'
-const int kMaxDigit = 57; // Last digit '9'
-const int kMinPasswordLength = 4;
-const int kMaxPasswordLength = 15;
-
-// A helper function to get the length of the generated password from
-// |max_length| retrieved from input password field.
-int GetLengthFromHint(int max_length, int default_length) {
- if (max_length >= kMinPasswordLength && max_length <= kMaxPasswordLength)
- return max_length;
- return default_length;
-}
-
-// We want the password to have uppercase, lowercase, and at least one number.
-bool VerifyPassword(const std::string& password) {
- int num_lower_case = 0;
- int num_upper_case = 0;
- int num_digits = 0;
-
- for (size_t i = 0; i < password.size(); ++i) {
- if (password[i] >= kMinUpper && password[i] <= kMaxUpper)
- ++num_upper_case;
- if (password[i] >= kMinLower && password[i] <= kMaxLower)
- ++num_lower_case;
- if (password[i] >= kMinDigit && password[i] <= kMaxDigit)
- ++num_digits;
- }
-
- return num_lower_case && num_upper_case && num_digits;
-}
-
-// Password generation function for unit testing, default to nullptr.
-// If not null, ForceFixPassword() will also always use |kMinDigit| as the digit
-// replacement, instead of choosing randomly.
-int (*g_test_override_generator)(char* word,
- char* hypenated_word,
- unsigned short minlen,
- unsigned short maxlen,
- unsigned int pass_mode) = nullptr;
-
-} // namespace
-
-namespace autofill {
-
-const int PasswordGeneratorFips181::kDefaultPasswordLength = 15;
-
-void ForceFixPassword(std::string* password) {
- for (char& it : *password) {
- if (islower(it)) {
- it = base::ToUpperASCII(it);
- break;
- }
- }
- for (std::string::reverse_iterator iter = password->rbegin();
- iter != password->rend(); ++iter) {
- if (islower(*iter)) {
- // Tests will use |PasswordGeneratorFips181::SetGeneratorForTest| to put a
- // non-random generator in |g_test_override_generator|. To eliminate the
- // other source of randomness, always fix the chosen digit to |kMinDigit|
- // in such case.
- *iter = g_test_override_generator == nullptr
- ? base::RandInt(kMinDigit, kMaxDigit)
- : kMinDigit;
- break;
- }
- }
-}
-
-PasswordGeneratorFips181::PasswordGeneratorFips181(int max_length)
- : password_length_(GetLengthFromHint(max_length, kDefaultPasswordLength)) {}
-PasswordGeneratorFips181::~PasswordGeneratorFips181() {}
-
-void PasswordGeneratorFips181::SetGeneratorForTest(
- int (*generator)(char* word,
- char* hypenated_word,
- unsigned short minlen,
- unsigned short maxlen,
- unsigned int pass_mode)) {
- g_test_override_generator = generator;
-}
-
-std::string PasswordGeneratorFips181::Generate() const {
- char password[255];
- char unused_hypenated_password[255];
- // Generate passwords that have numbers and upper and lower case letters.
- // No special characters included for now.
- unsigned int mode = S_NB | S_CL | S_SL;
-
- // Generate the password and fix afterwards if needed.
- auto generator =
- g_test_override_generator ? g_test_override_generator : gen_pron_pass;
- generator(password, unused_hypenated_password, password_length_,
- password_length_, mode);
- std::string str_password(password);
-
- if (VerifyPassword(str_password))
- return str_password;
-
- ForceFixPassword(&str_password);
- return str_password;
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_generator_fips181.h b/chromium/components/autofill/core/browser/password_generator_fips181.h
deleted file mode 100644
index 732cc732b8d..00000000000
--- a/chromium/components/autofill/core/browser/password_generator_fips181.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2013 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_PASSWORD_GENERATOR_FIPS181_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_FIPS181_H_
-
-#include <string>
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-
-namespace autofill {
-
-// Make sure that there is at least one upper case and one number in the
-// password. |password| must not be null, and must point to a string containing
-// at least 3 lower-case letters.
-extern void ForceFixPassword(std::string* password);
-
-// Class to generate random passwords. Currently we just use a generic algorithm
-// for all sites, but eventually we can incorporate additional information to
-// determine passwords that are likely to be accepted (i.e. use pattern field,
-// previous generated passwords, crowdsourcing, etc.)
-class PasswordGeneratorFips181 {
- public:
- // |max_length| is used as a hint for the generated password's length.
- explicit PasswordGeneratorFips181(int max_length);
- ~PasswordGeneratorFips181();
-
- // Returns a random password such that:
- // (1) Each character is guaranteed to be a non-whitespace printable ASCII
- // character.
- // (2) The generated password will contain AT LEAST one upper case letter, one
- // lower case letter, and one digit.
- // (3) The password length will be equal to |password_length_| (see comment
- // for the constructor).
- // Not thread safe.
- std::string Generate() const;
-
- // This method allows to substitute a replacement for the fips181 method
- // gen_pron_pass, used by the generator to generate the password. This is
- // useful in tests, for providing a deterministic generator.
- static void SetGeneratorForTest(int (*generator)(char* word,
- char* hypenated_word,
- unsigned short minlen,
- unsigned short maxlen,
- unsigned int pass_mode));
-
- private:
- // Unit test also need to access |kDefaultPasswordLength|.
- static const int kDefaultPasswordLength;
- FRIEND_TEST_ALL_PREFIXES(PasswordGeneratorFips181Test, PasswordLength);
-
- // The length of the generated password.
- const int password_length_;
-
- DISALLOW_COPY_AND_ASSIGN(PasswordGeneratorFips181);
-};
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_FIPS181_H_
diff --git a/chromium/components/autofill/core/browser/password_generator_fips181_fuzzer.cc b/chromium/components/autofill/core/browser/password_generator_fips181_fuzzer.cc
deleted file mode 100644
index 83d6b2618d4..00000000000
--- a/chromium/components/autofill/core/browser/password_generator_fips181_fuzzer.cc
+++ /dev/null
@@ -1,47 +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 <stddef.h>
-#include <stdint.h>
-
-#include <string>
-
-#include "components/autofill/core/browser/password_generator_fips181.h"
-
-namespace autofill {
-
-namespace {
-
-const char* g_password_text = nullptr;
-
-// The "PasswordGeneratorFips181" is a wrapper around Fips181's gen_pron_pass().
-// The former processes the random string from the latter and ensures that it
-// meets some constraints. GenerateForTest here substitutes for gen_pron_pass(),
-// so that the fuzzer tests the wrapper's logic rather than the third-party's
-// generator implementation.
-int GenerateForTest(char* word,
- char* hypenated_word,
- unsigned short minlen,
- unsigned short maxlen,
- unsigned int pass_mode) {
- strncpy(word, g_password_text, maxlen);
- g_password_text = nullptr;
- // Resize password to |maxlen|.
- word[maxlen] = '\0';
- return static_cast<int>(strlen(word));
-}
-
-} // namespace
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- autofill::PasswordGeneratorFips181::SetGeneratorForTest(GenerateForTest);
- std::string generator_string(reinterpret_cast<const char*>(data), size);
- g_password_text = generator_string.c_str();
- autofill::PasswordGeneratorFips181 pg(size);
- std::string password = pg.Generate();
- autofill::PasswordGeneratorFips181::SetGeneratorForTest(nullptr);
- return 0;
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_generator_fips181_unittest.cc b/chromium/components/autofill/core/browser/password_generator_fips181_unittest.cc
deleted file mode 100644
index 6188aa74421..00000000000
--- a/chromium/components/autofill/core/browser/password_generator_fips181_unittest.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2013 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 <stddef.h>
-#include <string.h>
-
-#include <locale>
-
-#include "components/autofill/core/browser/password_generator_fips181.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-void CheckPasswordCorrectness(const std::string& password) {
- int num_upper_case_letters = 0;
- int num_lower_case_letters = 0;
- int num_digits = 0;
- for (size_t i = 0; i < password.size(); i++) {
- if (isupper(password[i]))
- ++num_upper_case_letters;
- else if (islower(password[i]))
- ++num_lower_case_letters;
- else if (isdigit(password[i]))
- ++num_digits;
- }
- EXPECT_GT(num_upper_case_letters, 0) << password;
- EXPECT_GT(num_lower_case_letters, 0) << password;
- EXPECT_GT(num_digits, 0) << password;
-}
-
-const char* g_password_text = nullptr;
-
-int GenerateForTest(char* word,
- char* hypenated_word,
- unsigned short minlen,
- unsigned short maxlen,
- unsigned int pass_mode) {
- EXPECT_LE(minlen, maxlen);
- EXPECT_TRUE(word);
- EXPECT_TRUE(hypenated_word);
- EXPECT_TRUE(g_password_text) << "Set g_password_text before every call";
- strncpy(word, g_password_text, maxlen);
- g_password_text = nullptr;
- // Resize password to |maxlen|.
- word[maxlen] = '\0';
- EXPECT_GE(strlen(word), minlen)
- << "Make sure to provide enough characters in g_password_text";
- return static_cast<int>(strlen(word));
-}
-
-class PasswordGeneratorFips181Test : public ::testing::Test {
- public:
- PasswordGeneratorFips181Test() {
- autofill::PasswordGeneratorFips181::SetGeneratorForTest(GenerateForTest);
- }
- ~PasswordGeneratorFips181Test() override {
- autofill::PasswordGeneratorFips181::SetGeneratorForTest(nullptr);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PasswordGeneratorFips181Test);
-};
-
-} // namespace
-
-namespace autofill {
-
-TEST_F(PasswordGeneratorFips181Test, PasswordLength) {
- PasswordGeneratorFips181 pg1(10);
- g_password_text = "Aa12345678901234567890";
- std::string password = pg1.Generate();
- EXPECT_EQ(password.size(), 10u);
-
- PasswordGeneratorFips181 pg2(-1);
- g_password_text = "Aa12345678901234567890";
- password = pg2.Generate();
- EXPECT_EQ(
- password.size(),
- static_cast<size_t>(PasswordGeneratorFips181::kDefaultPasswordLength));
-
- PasswordGeneratorFips181 pg3(100);
- g_password_text = "Aa12345678901234567890";
- password = pg3.Generate();
- EXPECT_EQ(
- password.size(),
- static_cast<size_t>(PasswordGeneratorFips181::kDefaultPasswordLength));
-}
-
-TEST_F(PasswordGeneratorFips181Test, PasswordPattern) {
- PasswordGeneratorFips181 pg1(12);
- g_password_text = "012345678jkl";
- std::string password1 = pg1.Generate();
- CheckPasswordCorrectness(password1);
-
- PasswordGeneratorFips181 pg2(12);
- g_password_text = "abcDEFGHIJKL";
- std::string password2 = pg2.Generate();
- CheckPasswordCorrectness(password2);
-
- PasswordGeneratorFips181 pg3(12);
- g_password_text = "abcdefghijkl";
- std::string password3 = pg3.Generate();
- CheckPasswordCorrectness(password3);
-}
-
-TEST_F(PasswordGeneratorFips181Test, ForceFixPasswordTest) {
- std::string passwords_to_fix[] = {"nonumbersoruppercase",
- "nonumbersWithuppercase",
- "numbers3Anduppercase", "UmpAwgemHoc"};
- for (auto& password : passwords_to_fix) {
- ForceFixPassword(&password);
- CheckPasswordCorrectness(password);
- }
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_generator_proto_fuzzer.cc b/chromium/components/autofill/core/browser/password_generator_proto_fuzzer.cc
deleted file mode 100644
index 2967bc68616..00000000000
--- a/chromium/components/autofill/core/browser/password_generator_proto_fuzzer.cc
+++ /dev/null
@@ -1,15 +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/password_generator.h"
-#include "components/autofill/core/browser/proto/password_requirements.pb.h"
-#include "testing/libfuzzer/proto/lpm_interface.h"
-
-namespace autofill {
-
-DEFINE_PROTO_FUZZER(const PasswordRequirementsSpec& spec) {
- GeneratePassword(spec);
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_generator_unittest.cc b/chromium/components/autofill/core/browser/password_generator_unittest.cc
deleted file mode 100644
index 85343887168..00000000000
--- a/chromium/components/autofill/core/browser/password_generator_unittest.cc
+++ /dev/null
@@ -1,273 +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/password_generator.h"
-
-#include "base/logging.h"
-#include "components/autofill/core/browser/proto/password_requirements.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace autofill {
-
-namespace {
-
-// These are strings instead of enums to have an easy way of logging them.
-constexpr char kLowerCase[] = "lower_case";
-constexpr char kUpperCase[] = "upper_case";
-constexpr char kAlphabetic[] = "alphabetic";
-constexpr char kNumeric[] = "numeric";
-constexpr char kSymbol[] = "symbol";
-
-constexpr const char* kAllClassesButSymbols[] = {kLowerCase, kUpperCase,
- kAlphabetic, kNumeric};
-constexpr const char* kAllClassesButSymbolsAndAlphabetic[] = {
- kLowerCase, kUpperCase, kNumeric};
-
-bool IsCharInClass(base::char16 c, const std::string& class_name) {
- if (class_name == kLowerCase) {
- return 'a' <= c && c <= 'z';
- } else if (class_name == kUpperCase) {
- return 'A' <= c && c <= 'Z';
- } else if (class_name == kAlphabetic) {
- return IsCharInClass(c, kLowerCase) || IsCharInClass(c, kUpperCase);
- } else if (class_name == kNumeric) {
- return '0' <= c && c <= '9';
- }
- // Symbols are not covered because there is not fixed definition and because
- // symbols are treated like other character classes, so the importance of
- // dealing with them here is limited.
- NOTREACHED() << "Don't call IsCharInClass for symbols";
- return false;
-}
-
-size_t CountCharsInClass(const base::string16& password,
- const std::string& class_name) {
- size_t num = 0;
- for (base::char16 c : password) {
- if (IsCharInClass(c, class_name))
- ++num;
- }
- return num;
-}
-
-PasswordRequirementsSpec_CharacterClass* GetMutableCharClass(
- PasswordRequirementsSpec* spec,
- const std::string& class_name) {
- if (class_name == kLowerCase) {
- return spec->mutable_lower_case();
- } else if (class_name == kUpperCase) {
- return spec->mutable_upper_case();
- } else if (class_name == kAlphabetic) {
- return spec->mutable_alphabetic();
- } else if (class_name == kNumeric) {
- return spec->mutable_numeric();
- } else if (class_name == kSymbol) {
- return spec->mutable_symbols();
- }
- NOTREACHED();
- return nullptr;
-}
-
-class PasswordGeneratorTest : public testing::Test {
- public:
- PasswordGeneratorTest() { spec_.set_spec_version(1); }
- ~PasswordGeneratorTest() override = default;
-
- PasswordRequirementsSpec spec_;
-};
-
-TEST_F(PasswordGeneratorTest, PasswordLengthDefault) {
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
-}
-
-TEST_F(PasswordGeneratorTest, PasswordLengthMaxLength) {
- // Limit length according to requirement.
- spec_.set_max_length(kDefaultPasswordLength - 5u);
- EXPECT_EQ(kDefaultPasswordLength - 5u, GeneratePassword(spec_).length());
-
- // If max is higher than default, it does not matter.
- spec_.set_max_length(kDefaultPasswordLength + 5);
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
-}
-
-TEST_F(PasswordGeneratorTest, PasswordLengthMinLength) {
- // If min is smaller than default, it does not matter.
- spec_.set_min_length(kDefaultPasswordLength - 5u);
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
-
- // If a higher minimum length is explicitly set, use it.
- spec_.set_min_length(kDefaultPasswordLength + 5u);
- EXPECT_EQ(kDefaultPasswordLength + 5u, GeneratePassword(spec_).length());
-}
-
-TEST_F(PasswordGeneratorTest, PasswordLengthMinAndMax) {
- // Configure a contradicting min and max length. The max length wins.
- spec_.set_min_length(kDefaultPasswordLength + 5u);
- spec_.set_max_length(kDefaultPasswordLength - 5u);
- EXPECT_EQ(kDefaultPasswordLength - 5u, GeneratePassword(spec_).length());
-}
-
-TEST_F(PasswordGeneratorTest, MinCharFrequenciesRespected) {
- for (std::string char_class : kAllClassesButSymbols) {
- SCOPED_TRACE(char_class);
- spec_ = PasswordRequirementsSpec();
- spec_.set_spec_version(1);
- auto* char_class_config = GetMutableCharClass(&spec_, char_class);
- char_class_config->set_min(10);
- char_class_config->set_max(1000);
-
- base::string16 password = GeneratePassword(spec_);
- EXPECT_GE(CountCharsInClass(password, char_class), 10u);
- }
-}
-
-TEST_F(PasswordGeneratorTest, MinCharFrequenciesInsane) {
- // Nothing breaks if the min frequencies are way beyond what's possible
- // with the password length. In this case the generated passwor may contain
- // just characters of one class but its target length does not increase.
- for (std::string char_class : kAllClassesButSymbols) {
- SCOPED_TRACE(char_class);
- spec_ = PasswordRequirementsSpec();
- spec_.set_spec_version(1);
- auto* char_class_config = GetMutableCharClass(&spec_, char_class);
- char_class_config->set_min(1000);
- char_class_config->set_max(1000);
-
- base::string16 password = GeneratePassword(spec_);
- // At least some of the characters should be there.
- EXPECT_GE(CountCharsInClass(password, char_class), 1u);
- // But the password length does not change by minimum length requirements.
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
- }
-}
-
-TEST_F(PasswordGeneratorTest, MinCharFrequenciesBiggerThanMax) {
- spec_.set_min_length(15);
- spec_.set_max_length(15);
- for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
- auto* char_class_config = GetMutableCharClass(&spec_, char_class);
- // Min is reduced to max --> each class should have 5 representatives.
- char_class_config->set_min(10);
- char_class_config->set_max(5);
- }
-
- base::string16 password = GeneratePassword(spec_);
-
- for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
- SCOPED_TRACE(char_class);
- // Check that each character class is represented by 5 characters.
- EXPECT_EQ(5u, CountCharsInClass(password, char_class));
- }
- EXPECT_EQ(15u, password.length());
-}
-
-TEST_F(PasswordGeneratorTest, MaxFrequenciesRespected) {
- // Limit the maximum occurrences of characters of some classes to 2 and
- // validate that this is respected.
- for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
- SCOPED_TRACE(char_class);
- spec_ = PasswordRequirementsSpec();
- spec_.set_spec_version(1);
- auto* char_class_config = GetMutableCharClass(&spec_, char_class);
- char_class_config->set_max(2);
-
- base::string16 password = GeneratePassword(spec_);
- EXPECT_LE(CountCharsInClass(password, char_class), 2u);
- // Ensure that the other character classes that are not limited fill up the
- // password to the desired length.
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
- }
-}
-
-TEST_F(PasswordGeneratorTest, MaxFrequenciesInsufficient) {
- spec_.set_min_length(15);
- spec_.set_max_length(15);
- // Limit the maximum occurrences of characters of all classes to 2 which
- // sums up to less than 15.
- for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
- auto* char_class_config = GetMutableCharClass(&spec_, char_class);
- char_class_config->set_max(2);
- }
- // The resulting password can contain only 6 characters.
- EXPECT_EQ(6u, GeneratePassword(spec_).length());
-}
-
-TEST_F(PasswordGeneratorTest, CharacterSetCanBeOverridden) {
- // Limit lower case chars to 'a' and 'b' and require exacty 5 of those.
- spec_.mutable_lower_case()->set_character_set("ab");
- spec_.mutable_lower_case()->set_min(5);
- spec_.mutable_lower_case()->set_max(5);
- base::string16 password = GeneratePassword(spec_);
- // Then ensure that 'a's and 'b's are generated at the expected frequencies
- // as an indicator that the override was respected.
- size_t num_as_and_bs = 0;
- for (base::char16 c : password) {
- if (c == 'a' || c == 'b')
- ++num_as_and_bs;
- }
- EXPECT_EQ(5u, num_as_and_bs);
-}
-
-TEST_F(PasswordGeneratorTest, AllCharactersAreGenerated) {
- // Limit lower case chars to 'a' and 'b' and require exacty 5 of those.
- spec_.mutable_lower_case()->set_character_set("ab");
- spec_.mutable_lower_case()->set_min(5);
- spec_.mutable_lower_case()->set_max(5);
- bool success = false;
- // The chance of not seing both an 'a' and a 'b' in one run are only 2/32 per
- // run. Ultimately we should see success. If none of the 100 generated
- // passwords contained an 'a' (or 'b'), then this would indicate that the
- // generator does not fully use the character set (probably due to an
- // off-by-one error).
- for (size_t attempt = 0; attempt < 100; ++attempt) {
- base::string16 password = GeneratePassword(spec_);
- size_t num_as = 0;
- size_t num_bs = 0;
- for (base::char16 c : password) {
- if (c == 'a')
- ++num_as;
- if (c == 'b')
- ++num_bs;
- }
- if (num_as > 0u && num_bs > 0u) {
- success = true;
- break;
- }
- }
- EXPECT_TRUE(success);
-}
-
-TEST_F(PasswordGeneratorTest, PasswordCanBeGeneratedWithEmptyCharSet) {
- // If the character set is empty, min and max should be ignored.
- spec_.mutable_lower_case()->set_character_set("");
- spec_.mutable_lower_case()->set_min(5);
- spec_.mutable_lower_case()->set_max(5);
- base::string16 password = GeneratePassword(spec_);
- EXPECT_EQ(0u, CountCharsInClass(password, kLowerCase));
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
-}
-
-TEST_F(PasswordGeneratorTest, AllCharactersForbidden) {
- spec_.set_min_length(kDefaultPasswordLength + 2);
- spec_.set_max_length(kDefaultPasswordLength + 2);
- for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
- auto* char_class_config = GetMutableCharClass(&spec_, char_class);
- char_class_config->set_max(0);
- }
- // If it is impossible to generate a password (due to max = 0), the generator
- // delivers a password as per default spec and ignores everything else.
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
-}
-
-TEST_F(PasswordGeneratorTest, ZeroLength) {
- spec_.set_min_length(0);
- spec_.set_max_length(0);
- // If the generated password following the spec is empty, a default spec is
- // applied.
- EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
-}
-
-} // namespace
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher.h b/chromium/components/autofill/core/browser/password_requirements_spec_fetcher.h
deleted file mode 100644
index d07997de389..00000000000
--- a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher.h
+++ /dev/null
@@ -1,41 +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.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_H_
-
-#include "base/callback.h"
-#include "url/gurl.h"
-
-namespace autofill {
-
-class PasswordRequirementsSpec;
-
-// Fetches PasswordRequirementsSpec for a specific origin.
-class PasswordRequirementsSpecFetcher {
- public:
- using FetchCallback =
- base::OnceCallback<void(const PasswordRequirementsSpec&)>;
-
- virtual ~PasswordRequirementsSpecFetcher() = default;
-
- // Fetches a configuration for |origin|.
- //
- // |origin| references the origin in the PasswordForm for which rules need to
- // be fetched.
- //
- // The |callback| must remain valid until called back, but this class may be
- // destroyed before the |callback| has been triggered.
- //
- // Fetch() may be called multiple times concurrently. Requests are batched
- // if possible.
- //
- // If the network request fails or times out, the callback receives an empty
- // spec.
- virtual void Fetch(GURL origin, FetchCallback callback) = 0;
-};
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_H_
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
deleted file mode 100644
index ff4367110f0..00000000000
--- a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.cc
+++ /dev/null
@@ -1,315 +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/password_requirements_spec_fetcher_impl.h"
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/md5.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "components/autofill/core/browser/password_requirements_spec_printer.h"
-#include "components/autofill/core/browser/proto/password_requirements.pb.h"
-#include "components/autofill/core/browser/proto/password_requirements_shard.pb.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_errors.h"
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "services/network/public/cpp/resource_request.h"
-#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/cpp/simple_url_loader.h"
-#include "url/url_canon.h"
-
-namespace autofill {
-
-PasswordRequirementsSpecFetcherImpl::PasswordRequirementsSpecFetcherImpl(
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- int version,
- size_t prefix_length,
- int timeout)
- : url_loader_factory_(std::move(url_loader_factory)),
- version_(version),
- prefix_length_(prefix_length),
- timeout_(timeout) {
- DCHECK_GE(version_, 0);
- DCHECK_LE(prefix_length_, 32u);
- DCHECK_GE(timeout_, 0);
-}
-
-PasswordRequirementsSpecFetcherImpl::~PasswordRequirementsSpecFetcherImpl() =
- default;
-
-PasswordRequirementsSpecFetcherImpl::LookupInFlight::LookupInFlight() = default;
-PasswordRequirementsSpecFetcherImpl::LookupInFlight::~LookupInFlight() =
- default;
-
-namespace {
-
-// Hashes the eTLD+1 of |origin| via MD5 and returns a filename with the first
-// |prefix_length| bits populated. The returned value corresponds to the first
-// 4 bytes of the truncated MD5 prefix in hex notation.
-// For example:
-// "https://www.example.com" has a eTLD+1 of "example.com".
-// The MD5SUM of that is 5ababd603b22780302dd8d83498e5172.
-// Stripping this to the first 8 bits (prefix_length = 8) gives
-// 500000000000000000000000000000000. The file name is always cut to the first
-// four bytes, i.e. 5000 in this example.
-std::string GetHashPrefix(const GURL& origin, size_t prefix_length) {
- DCHECK_LE(prefix_length, 32u);
- std::string domain_and_registry =
- net::registry_controlled_domains::GetDomainAndRegistry(
- origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
-
- base::MD5Digest digest;
- base::MD5Sum(domain_and_registry.data(), domain_and_registry.size(), &digest);
-
- for (size_t i = 0; i < base::size(digest.a); ++i) {
- if (prefix_length >= 8) {
- prefix_length -= 8;
- continue;
- } else {
- // Determine the |prefix_length| most significant bits by calculating
- // the 8 - |prefix_length| least significant bits and inverting the
- // result.
- digest.a[i] &= ~((1 << (8 - prefix_length)) - 1);
- prefix_length = 0;
- }
- }
-
- return base::MD5DigestToBase16(digest).substr(0, 4);
-}
-
-// Returns the URL on gstatic.com where the passwords spec file can be found
-// that contains data for |hash_prefix|.
-GURL GetUrlForRequirementsSpec(int version, const std::string& hash_prefix) {
- return GURL(base::StringPrintf(
- "https://www.gstatic.com/chrome/autofill/password_generation_specs/%d/%s",
- version, hash_prefix.c_str()));
-}
-
-} // namespace
-
-void PasswordRequirementsSpecFetcherImpl::Fetch(
- GURL origin,
- FetchCallback callback) {
- DCHECK(origin.is_valid());
- VLOG(1) << "Fetching password requirements spec for " << origin;
-
- if (!url_loader_factory_) {
- VLOG(1) << "No url_logger_factory_ available";
- TriggerCallback(std::move(callback), ResultCode::kErrorNoUrlLoader,
- PasswordRequirementsSpec());
- return;
- }
-
- if (!url_loader_factory_) {
- TriggerCallback(std::move(callback), ResultCode::kErrorNoUrlLoader,
- PasswordRequirementsSpec());
- return;
- }
-
- if (!url_loader_factory_) {
- TriggerCallback(std::move(callback), ResultCode::kErrorNoUrlLoader,
- PasswordRequirementsSpec());
- return;
- }
-
- if (!origin.is_valid() || origin.HostIsIPAddress() ||
- !origin.SchemeIsHTTPOrHTTPS()) {
- VLOG(1) << "No valid origin";
- TriggerCallback(std::move(callback), ResultCode::kErrorInvalidOrigin,
- PasswordRequirementsSpec());
- return;
- }
-
- // Canonicalize away trailing periods in hostname.
- while (!origin.host().empty() && origin.host().back() == '.') {
- std::string new_host = origin.host().substr(0, origin.host().length() - 1);
- url::Replacements<char> replacements;
- replacements.SetHost(new_host.c_str(),
- url::Component(0, new_host.length()));
- origin = origin.ReplaceComponents(replacements);
- }
-
- std::string hash_prefix = GetHashPrefix(origin, prefix_length_);
-
- // If a lookup is happening already, just register another callback.
- auto iter = lookups_in_flight_.find(hash_prefix);
- if (iter != lookups_in_flight_.end()) {
- iter->second->callbacks.push_back(
- std::make_pair(origin, std::move(callback)));
- VLOG(1) << "Lookup already in flight";
- return;
- }
-
- // Start another lookup otherwise.
- auto lookup = std::make_unique<LookupInFlight>();
- lookup->callbacks.push_back(std::make_pair(origin, std::move(callback)));
- lookup->start_of_request = base::TimeTicks::Now();
-
- net::NetworkTrafficAnnotationTag traffic_annotation =
- net::DefineNetworkTrafficAnnotation("password_requirements_spec_fetch",
- R"(
- semantics {
- sender: "Password requirements specification fetcher"
- description:
- "Fetches the password requirements for a set of domains whose origin "
- "hash starts with a certain prefix."
- trigger:
- "When the user triggers a password generation (this can happen by "
- "just focussing a password field)."
- data:
- "The URL encodes a hash prefix from which it is not possible to "
- "derive the original origin. No user information is sent."
- destination: WEBSITE
- }
- policy {
- cookies_allowed: NO
- setting: "Unconditionally enabled."
- policy_exception_justification:
- "Not implemented, considered not useful."
- })");
- auto resource_request = std::make_unique<network::ResourceRequest>();
- resource_request->url = GetUrlForRequirementsSpec(version_, hash_prefix);
- resource_request->load_flags = net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA;
- lookup->url_loader = network::SimpleURLLoader::Create(
- std::move(resource_request), traffic_annotation);
- lookup->url_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
- url_loader_factory_.get(),
- base::BindOnce(&PasswordRequirementsSpecFetcherImpl::OnFetchComplete,
- base::Unretained(this), hash_prefix));
-
- lookup->download_timer.Start(
- FROM_HERE, base::TimeDelta::FromMilliseconds(timeout_),
- base::BindRepeating(&PasswordRequirementsSpecFetcherImpl::OnFetchTimeout,
- base::Unretained(this), hash_prefix));
-
- lookups_in_flight_[hash_prefix] = std::move(lookup);
-}
-
-void PasswordRequirementsSpecFetcherImpl::OnFetchComplete(
- const std::string& hash_prefix,
- std::unique_ptr<std::string> response_body) {
- std::unique_ptr<LookupInFlight> lookup = RemoveLookupInFlight(hash_prefix);
-
- lookup->download_timer.Stop();
- UMA_HISTOGRAM_TIMES("PasswordManager.RequirementsSpecFetcher.NetworkDuration",
- base::TimeTicks::Now() - lookup->start_of_request);
- base::UmaHistogramSparse(
- "PasswordManager.RequirementsSpecFetcher.NetErrorCode",
- lookup->url_loader->NetError());
- if (lookup->url_loader->ResponseInfo() &&
- lookup->url_loader->ResponseInfo()->headers) {
- base::UmaHistogramSparse(
- "PasswordManager.RequirementsSpecFetcher.HttpResponseCode",
- lookup->url_loader->ResponseInfo()->headers->response_code());
- }
-
- if (!response_body || lookup->url_loader->NetError() != net::Error::OK) {
- VLOG(1) << "Fetch for " << hash_prefix << ": failed to fetch "
- << lookup->url_loader->NetError();
- TriggerCallbackToAll(&lookup->callbacks, ResultCode::kErrorFailedToFetch,
- PasswordRequirementsSpec());
- return;
- }
-
- PasswordRequirementsShard shard;
- if (!shard.ParseFromString(*response_body)) {
- VLOG(1) << "Fetch for " << hash_prefix << ": failed to parse response";
- TriggerCallbackToAll(&lookup->callbacks, ResultCode::kErrorFailedToParse,
- PasswordRequirementsSpec());
- return;
- }
- for (auto& callback_pair : lookup->callbacks) {
- const GURL& origin = callback_pair.first;
- FetchCallback& callback_function = callback_pair.second;
-
- // Search shard for matches for origin by looking up the (canonicalized)
- // host name and then stripping domain prefixes until the eTLD+1 is reached.
- DCHECK(!origin.HostIsIPAddress());
- // |host| is a std::string instead of StringPiece as the protbuf::Map
- // implementation does not support StringPieces as parameters for find.
- std::string host = origin.host();
- auto host_iter = shard.specs().find(host);
- if (host_iter != shard.specs().end()) {
- const PasswordRequirementsSpec& spec = host_iter->second;
- VLOG(1) << "Found for " << host << ": " << spec;
- TriggerCallback(std::move(callback_function), ResultCode::kFoundSpec,
- spec);
- continue;
- }
-
- bool found_entry = false;
- const std::string domain_and_registry =
- net::registry_controlled_domains::GetDomainAndRegistry(
- origin,
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- while (host.length() > 0 && host != domain_and_registry) {
- size_t pos = host.find('.');
- if (pos != std::string::npos) { // strip prefix
- host = host.substr(pos + 1);
- } else {
- break;
- }
- // If an entry has ben found, exit with that.
- auto it = shard.specs().find(host);
- if (it != shard.specs().end()) {
- const PasswordRequirementsSpec& spec = it->second;
- found_entry = true;
- VLOG(1) << "Found for " << host << ": " << spec;
- TriggerCallback(std::move(callback_function), ResultCode::kFoundSpec,
- spec);
- break;
- }
- }
-
- if (!found_entry) {
- VLOG(1) << "Found no entry for " << host;
- TriggerCallback(std::move(callback_function), ResultCode::kFoundNoSpec,
- PasswordRequirementsSpec());
- }
- }
-}
-
-void PasswordRequirementsSpecFetcherImpl::OnFetchTimeout(
- const std::string& hash_prefix) {
- std::unique_ptr<LookupInFlight> lookup = RemoveLookupInFlight(hash_prefix);
- UMA_HISTOGRAM_TIMES("PasswordManager.RequirementsSpecFetcher.NetworkDuration",
- base::TimeTicks::Now() - lookup->start_of_request);
- TriggerCallbackToAll(&lookup->callbacks, ResultCode::kErrorTimeout,
- PasswordRequirementsSpec());
-}
-
-void PasswordRequirementsSpecFetcherImpl::TriggerCallbackToAll(
- std::list<std::pair<GURL, FetchCallback>>* callbacks,
- ResultCode result,
- const PasswordRequirementsSpec& spec) {
- for (auto& callback_pair : *callbacks) {
- TriggerCallback(std::move(callback_pair.second), result, spec);
- }
-}
-
-void PasswordRequirementsSpecFetcherImpl::TriggerCallback(
- FetchCallback callback,
- ResultCode result,
- const PasswordRequirementsSpec& spec) {
- UMA_HISTOGRAM_ENUMERATION("PasswordManager.RequirementsSpecFetcher.Result",
- result);
- std::move(callback).Run(spec);
-}
-
-std::unique_ptr<PasswordRequirementsSpecFetcherImpl::LookupInFlight>
-PasswordRequirementsSpecFetcherImpl::RemoveLookupInFlight(
- const std::string& hash_prefix) {
- DCHECK(lookups_in_flight_.find(hash_prefix) != lookups_in_flight_.end());
- std::unique_ptr<LookupInFlight> lookup;
- std::swap(lookup, lookups_in_flight_[hash_prefix]);
- lookups_in_flight_.erase(hash_prefix);
- return lookup;
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.h b/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.h
deleted file mode 100644
index 3d22b0e8af9..00000000000
--- a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_impl.h
+++ /dev/null
@@ -1,143 +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.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_IMPL_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_IMPL_H_
-
-#include <list>
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/timer/timer.h"
-#include "components/autofill/core/browser/password_requirements_spec_fetcher.h"
-#include "url/gurl.h"
-
-namespace network {
-class SharedURLLoaderFactory;
-class SimpleURLLoader;
-} // namespace network
-
-namespace autofill {
-
-class PasswordRequirementsSpec;
-
-// A concrete implementation for PasswordRequirementsSpecFetcher that talks
-// to the network.
-class PasswordRequirementsSpecFetcherImpl
- : public PasswordRequirementsSpecFetcher {
- public:
- // This enum is used in histograms. Do not change or reuse values.
- enum class ResultCode {
- // Fetched spec file, parsed it, but found no entry for the origin.
- kFoundNoSpec = 0,
- // Fetched spec file, parsed it and found an entry.
- kFoundSpec = 1,
- // The origin is an IP address, not HTTP/HTTPS, or not a valid URL.
- kErrorInvalidOrigin = 2,
- // Server responded with an empty document or an error code.
- kErrorFailedToFetch = 3,
- // Server timed out.
- kErrorTimeout = 4,
- // Server responded with a document but it could not be parsed.
- kErrorFailedToParse = 5,
- // No URL loader configured for the PasswordRequirementsSpecFetcher.
- kErrorNoUrlLoader = 6,
- kMaxValue = kErrorNoUrlLoader,
- };
-
- // See the member variables for explanations of these parameters.
- PasswordRequirementsSpecFetcherImpl(
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- int version,
- size_t prefix_length,
- int timeout);
- ~PasswordRequirementsSpecFetcherImpl() override;
-
- // Implementation for PasswordRequirementsSpecFetcher:
- void Fetch(GURL origin, FetchCallback callback) override;
-
- private:
- // This structure bundles all data that are associated to a network request
- // for a file with a specific hash prefix.
- struct LookupInFlight {
- LookupInFlight();
- ~LookupInFlight();
-
- // Callbacks to be called if the network request resolves or is aborted.
- // The GURL represents the origin due to which a spec was fetched.
- // Used a std::list instead of std::vector to grow this cheaply.
- std::list<std::pair<GURL, FetchCallback>> callbacks;
-
- // Timer to kill pending downloads after |timeout_|.
- base::OneShotTimer download_timer;
-
- std::unique_ptr<network::SimpleURLLoader> url_loader;
-
- // Time when the network request is started.
- base::TimeTicks start_of_request;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LookupInFlight);
- };
-
- // These are the two ways how a network request can end. The functions remove
- // the entry corresponding to |hash_prefix| out of |lookups_in_flight_| as
- // their first order of business.
- void OnFetchComplete(const std::string& hash_prefix,
- std::unique_ptr<std::string> response_body);
- void OnFetchTimeout(const std::string& hash_prefix);
-
- // Calls all |callbacks| in order. Note that these callbacks are OnceCallback
- // instances. Therefore, entries are reset after this function returns.
- void TriggerCallbackToAll(
- std::list<std::pair<GURL, FetchCallback>>* callbacks,
- ResultCode result,
- const PasswordRequirementsSpec& spec);
-
- // Calls the |callback| with the specific data and records some metrics.
- void TriggerCallback(FetchCallback callback,
- ResultCode result,
- const PasswordRequirementsSpec& spec);
-
- std::unique_ptr<LookupInFlight> RemoveLookupInFlight(
- const std::string& hash_prefix);
-
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
-
- // A version counter for requirements specs. If data changes on the server,
- // a new version number is pushed out to prevent that clients continue
- // using old cached data. This allows setting the HTTP caching expiration to
- // infinity.
- int version_;
-
- // The fetcher determines the URL of the spec file by first hashing the eTLD+1
- // of |origin| and then taking the first |prefix_length_| bits of the hash
- // value as part of the file name. (See the code for details.)
- // |prefix_length_| should always be <= 32 as filenames are limited to the
- // first 4 bytes of the hash prefix.
- size_t prefix_length_;
-
- // Timeout in milliseconds after which any ongoing fetch operation is
- // canceled.
- int timeout_;
-
- // Data about network requests in flight.
- // The key is the name of the file being fetched without the common URL prefix
- // (e.g. "0000"). The value contains callbacks that should process the result
- // and a timer to cancel the lookup after some time.
- // The invariant of |lookups_in_flight_| is that entries exist from the
- // time of starting the network request until receiving the response or a
- // timeout.
- std::map<std::string, std::unique_ptr<LookupInFlight>> lookups_in_flight_;
-
- DISALLOW_COPY_AND_ASSIGN(PasswordRequirementsSpecFetcherImpl);
-};
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_IMPL_H_
diff --git a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_unittest.cc b/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_unittest.cc
deleted file mode 100644
index 3f7bd199b1f..00000000000
--- a/chromium/components/autofill/core/browser/password_requirements_spec_fetcher_unittest.cc
+++ /dev/null
@@ -1,343 +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/password_requirements_spec_fetcher_impl.h"
-
-#include "base/logging.h"
-#include "base/test/bind_test_util.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "components/autofill/core/browser/proto/password_requirements.pb.h"
-#include "components/autofill/core/browser/proto/password_requirements_shard.pb.h"
-#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
-#include "services/network/test/test_url_loader_factory.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace autofill {
-
-namespace {
-
-// URL prefix for spec requests.
-#define SERVER_URL \
- "https://www.gstatic.com/chrome/autofill/password_generation_specs/"
-
-TEST(PasswordRequirementsSpecFetcherTest, FetchData) {
- using ResultCode = PasswordRequirementsSpecFetcherImpl::ResultCode;
-
- // An empty spec is returned for all error cases (time outs, server responding
- // with anything but HTTP_OK).
- PasswordRequirementsSpec empty_spec;
-
- PasswordRequirementsSpec success_spec_for_example_com;
- success_spec_for_example_com.set_min_length(17);
- PasswordRequirementsSpec success_spec_for_m_example_com;
- success_spec_for_m_example_com.set_min_length(18);
- PasswordRequirementsSpec spec_for_ip;
- success_spec_for_m_example_com.set_min_length(19);
- PasswordRequirementsSpec success_spec_for_uber_example_com;
- success_spec_for_uber_example_com.set_min_length(20);
-
- std::string serialized_shard;
- PasswordRequirementsShard shard;
- (*shard.mutable_specs())["example.com"] = success_spec_for_example_com;
- (*shard.mutable_specs())["m.example.com"] = success_spec_for_m_example_com;
- // This spec is stored in the buffer but is not expected to be processed.
- // Only real hostnames are supposed to be parsed.
- (*shard.mutable_specs())["192.168.1.1"] = spec_for_ip;
- // Punycoded entry.
- (*shard.mutable_specs())["xn--ber-example-shb.com"] =
- success_spec_for_uber_example_com;
- shard.SerializeToString(&serialized_shard);
-
- // If this magic timeout value is set, simulate a timeout.
- const int kMagicTimeout = 10;
-
- struct {
- // Name of the test for log output.
- const char* test_name;
-
- // Origin for which the spec is fetched.
- const char* origin;
-
- // Current configuration that would be set via Finch.
- int generation = 1;
- int prefix_length = 32;
- int timeout = 1000;
-
- // Handler for the spec requests.
- const char* requested_url;
- std::string response_content;
- net::HttpStatusCode response_status = net::HTTP_OK;
-
- // Expected spec.
- PasswordRequirementsSpec* expected_spec;
- ResultCode expected_result;
- } tests[] = {
- {
- .test_name = "Business as usual",
- .origin = "https://www.example.com",
- // See echo -n example.com | md5sum | cut -b 1-4
- .requested_url = SERVER_URL "1/5aba",
- .response_content = serialized_shard,
- .expected_spec = &success_spec_for_example_com,
- .expected_result = ResultCode::kFoundSpec,
- },
- {
- .test_name = "Parts before the eTLD+1 don't matter",
- // m.example.com instead of www.example.com creates the same hash
- // prefix.
- .origin = "https://m.example.com",
- .requested_url = SERVER_URL "1/5aba",
- .response_content = serialized_shard,
- // But shard contains a special entry for m.example.com, so verify
- // that the more specific element is returned.
- .expected_spec = &success_spec_for_m_example_com,
- .expected_result = ResultCode::kFoundSpec,
- },
- {
- .test_name = "The generation is encoded in the url",
- .origin = "https://www.example.com",
- // Here the test differs from the default:
- .generation = 2,
- .requested_url = SERVER_URL "2/5aba",
- .response_content = serialized_shard,
- .expected_spec = &success_spec_for_example_com,
- .expected_result = ResultCode::kFoundSpec,
- },
- {
- .test_name = "Shorter prefixes are reflected in the URL",
- .origin = "https://m.example.com",
- // The prefix "5abc" starts with 0b01011010. If the prefix is limited
- // to the first 3 bits, b0100 = 0x4 remains and the rest is zeroed
- // out.
- .prefix_length = 3,
- .requested_url = SERVER_URL "1/4000",
- .response_content = serialized_shard,
- .expected_spec = &success_spec_for_m_example_com,
- .expected_result = ResultCode::kFoundSpec,
- },
- {
- .test_name = "Simulate a 404 response",
- .origin = "https://www.example.com",
- .requested_url = SERVER_URL "1/5aba",
- .response_content = "Not found",
- // If a file is not found on the server, the spec should be empty.
- .response_status = net::HTTP_NOT_FOUND,
- .expected_spec = &empty_spec,
- .expected_result = ResultCode::kErrorFailedToFetch,
- },
- {
- .test_name = "Simulate a timeout",
- .origin = "https://www.example.com",
- // This simulates a timeout.
- .timeout = kMagicTimeout,
- // This makes sure that the server does not respond by itself as
- // TestURLLoaderFactory reacts as if a response has been added to
- // a URL.
- .requested_url = SERVER_URL "dont_respond",
- .response_content = serialized_shard,
- .expected_spec = &empty_spec,
- .expected_result = ResultCode::kErrorTimeout,
- },
- {
- .test_name = "Zero prefix",
- .origin = "https://www.example.com",
- // A zero prefix will be the hard-coded Finch default and should work.
- .prefix_length = 0,
- .requested_url = SERVER_URL "1/0000",
- .response_content = serialized_shard,
- .expected_spec = &success_spec_for_example_com,
- .expected_result = ResultCode::kFoundSpec,
- },
- {
- .test_name = "IP addresses give the empty spec",
- .origin = "http://192.168.1.1/",
- // By setting the prefix to 0, the URL of the shard is predefined,
- // but actually, not network request should be sent as password
- // requirements are not supported for IP addresses.
- .prefix_length = 0,
- .requested_url = SERVER_URL "0/0000",
- .response_content = serialized_shard,
- .expected_spec = &empty_spec,
- .expected_result = ResultCode::kErrorInvalidOrigin,
- },
- {
- .test_name = "IP addresses give the empty spec",
- .origin = "chrome://settings",
- // By setting the prefix to 0, the URL of the shard is predefined,
- // but actually, not network request should be sent as password
- // requirements are not supported the chrome:// scheme.
- .prefix_length = 0,
- .requested_url = SERVER_URL "0/0000",
- .response_content = serialized_shard,
- .expected_spec = &empty_spec,
- .expected_result = ResultCode::kErrorInvalidOrigin,
- },
- {
- .test_name = "Trailing period is normalized",
- // Despite the trailing '.', everything is like for example.com
- .origin = "https://www.example.com.",
- .requested_url = SERVER_URL "1/5aba",
- .response_content = serialized_shard,
- .expected_spec = &success_spec_for_example_com,
- .expected_result = ResultCode::kFoundSpec,
- },
- {
- .test_name = "Test punycoding",
- .origin = "https://www.über-example.com",
- // See echo -n xn--ber-example-shb.com | md5sum | cut -b 1-4
- .requested_url = SERVER_URL "1/e5db",
- .response_content = serialized_shard,
- .expected_spec = &success_spec_for_uber_example_com,
- .expected_result = ResultCode::kFoundSpec,
- },
- {
- .test_name = "Test no entry",
- .origin = "https://www.no-entry.com",
- // See echo -n no-entry.com | md5sum | cut -b 1-4
- .requested_url = SERVER_URL "1/7579",
- .response_content = serialized_shard,
- .expected_spec = &empty_spec,
- .expected_result = ResultCode::kFoundNoSpec,
- },
- };
-
- for (const auto& test : tests) {
- SCOPED_TRACE(test.test_name);
- base::HistogramTester histogram_tester;
-
- base::test::ScopedTaskEnvironment environment(
- base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
- network::TestURLLoaderFactory loader_factory;
- loader_factory.AddResponse(test.requested_url, test.response_content,
- test.response_status);
-
- // Data to be collected from the callback.
- bool callback_called = false;
- PasswordRequirementsSpec returned_spec;
-
- // Trigger the network request and record data of the callback.
- PasswordRequirementsSpecFetcherImpl fetcher(
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &loader_factory),
- test.generation, test.prefix_length, test.timeout);
- auto callback =
- base::BindLambdaForTesting([&](const PasswordRequirementsSpec& spec) {
- callback_called = true;
- returned_spec = spec;
- });
- fetcher.Fetch(GURL(test.origin), callback);
-
- environment.RunUntilIdle();
-
- if (test.timeout == kMagicTimeout) {
- // Make sure that the request takes longer than the timeout and gets
- // killed by the timer.
- environment.FastForwardBy(
- base::TimeDelta::FromMilliseconds(2 * kMagicTimeout));
- environment.RunUntilIdle();
- }
-
- ASSERT_TRUE(callback_called);
- EXPECT_EQ(test.expected_spec->SerializeAsString(),
- returned_spec.SerializeAsString());
- histogram_tester.ExpectUniqueSample(
- "PasswordManager.RequirementsSpecFetcher.Result", test.expected_result,
- 1u);
- }
-}
-
-// Test two requests to fetch the same shard before the network responded.
-// In this case, only one network request should be sent.
-TEST(PasswordRequirementsSpecFetcherTest, FetchDataInterleaved) {
- for (bool simulate_timeout : {false, true}) {
- SCOPED_TRACE(::testing::Message()
- << "Simulate timeout? " << simulate_timeout);
-
- // Set up the data that will be served.
- std::string serialized_shard;
- PasswordRequirementsShard shard;
- (*shard.mutable_specs())["a.com"].set_min_length(17);
- (*shard.mutable_specs())["b.com"].set_min_length(18);
- shard.SerializeToString(&serialized_shard);
-
- base::test::ScopedTaskEnvironment environment(
- base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
- network::TestURLLoaderFactory loader_factory;
-
- // Target into which data will be written by the callback.
- PasswordRequirementsSpec spec_for_a;
- PasswordRequirementsSpec spec_for_b;
- // Set some values to see whether they get overridden by the callback.
- spec_for_a.set_min_length(1);
- spec_for_b.set_min_length(1);
-
- const int kVersion = 1;
- // With a prefix length of 0, we guarantee that only one shard exists
- // and therefore that the requests go to the same endpoint and can be
- // unified into one network request.
- const size_t kPrefixLength = 0;
- const int kTimeout = 1000;
- PasswordRequirementsSpecFetcherImpl fetcher(
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &loader_factory),
- kVersion, kPrefixLength, kTimeout);
-
- fetcher.Fetch(
- GURL("http://a.com"),
- base::BindLambdaForTesting(
- [&](const PasswordRequirementsSpec& spec) { spec_for_a = spec; }));
- fetcher.Fetch(
- GURL("http://b.com"),
- base::BindLambdaForTesting(
- [&](const PasswordRequirementsSpec& spec) { spec_for_b = spec; }));
-
- EXPECT_EQ(1, loader_factory.NumPending());
-
- if (simulate_timeout) {
- environment.FastForwardBy(
- base::TimeDelta::FromMilliseconds(2 * kTimeout));
- environment.RunUntilIdle();
- EXPECT_FALSE(spec_for_a.has_min_length());
- EXPECT_FALSE(spec_for_b.has_min_length());
- } else {
- loader_factory.AddResponse(SERVER_URL "1/0000", serialized_shard,
- net::HTTP_OK);
- environment.RunUntilIdle();
-
- EXPECT_EQ(17u, spec_for_a.min_length());
- EXPECT_EQ(18u, spec_for_b.min_length());
- }
- }
-}
-
-// In case of incognito mode, we won't have a URL loader factory.
-// Test that an empty spec is returned by the spec fetcher in this case.
-TEST(PasswordRequirementsSpecFetcherTest, FetchDataWithoutURLLoaderFactory) {
- base::test::ScopedTaskEnvironment environment;
-
- // Target into which data will be written by the callback.
- PasswordRequirementsSpec received_spec;
- // Set some values to see whether they get overridden by the callback.
- received_spec.set_min_length(1);
-
- const int kVersion = 1;
- const size_t kPrefixLength = 0;
- const int kTimeout = 1000;
- PasswordRequirementsSpecFetcherImpl fetcher(nullptr, kVersion, kPrefixLength,
- kTimeout);
-
- fetcher.Fetch(
- GURL("http://a.com"),
- base::BindLambdaForTesting(
- [&](const PasswordRequirementsSpec& spec) { received_spec = spec; }));
- environment.RunUntilIdle();
- EXPECT_FALSE(received_spec.has_min_length());
-}
-
-#undef SERVER_URL
-
-} // namespace
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_requirements_spec_printer.cc b/chromium/components/autofill/core/browser/password_requirements_spec_printer.cc
deleted file mode 100644
index dd7049d34da..00000000000
--- a/chromium/components/autofill/core/browser/password_requirements_spec_printer.cc
+++ /dev/null
@@ -1,48 +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/password_requirements_spec_printer.h"
-
-namespace autofill {
-
-std::ostream& operator<<(
- std::ostream& out,
- const PasswordRequirementsSpec::CharacterClass& character_class) {
- out << "{";
- if (character_class.has_character_set())
- out << "character_set: \"" << character_class.character_set() << "\", ";
- if (character_class.has_min())
- out << "min: " << character_class.min() << ", ";
- if (character_class.has_max())
- out << "max: " << character_class.max() << ", ";
- out << "}";
- return out;
-}
-
-std::ostream& operator<<(std::ostream& out,
- const PasswordRequirementsSpec& spec) {
- out << "{";
- if (spec.has_priority())
- out << "priority: " << spec.priority() << ", ";
- if (spec.has_spec_version())
- out << "spec_version: " << spec.spec_version() << ", ";
- if (spec.has_min_length())
- out << "min_length: " << spec.min_length() << ", ";
- if (spec.has_max_length())
- out << "max_length: " << spec.max_length() << ", ";
- if (spec.has_lower_case())
- out << "lower_case: " << spec.lower_case() << ", ";
- if (spec.has_upper_case())
- out << "upper_case: " << spec.upper_case() << ", ";
- if (spec.has_alphabetic())
- out << "alphabetic: " << spec.alphabetic() << ", ";
- if (spec.has_numeric())
- out << "numeric: " << spec.alphabetic() << ", ";
- if (spec.has_symbols())
- out << "symbols: " << spec.symbols() << ", ";
- out << "}";
- return out;
-}
-
-} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/password_requirements_spec_printer.h b/chromium/components/autofill/core/browser/password_requirements_spec_printer.h
deleted file mode 100644
index 81169340bce..00000000000
--- a/chromium/components/autofill/core/browser/password_requirements_spec_printer.h
+++ /dev/null
@@ -1,23 +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.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_PRINTER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_PRINTER_H_
-
-#include <ostream>
-
-#include "components/autofill/core/browser/proto/password_requirements.pb.h"
-
-namespace autofill {
-
-std::ostream& operator<<(
- std::ostream& out,
- const PasswordRequirementsSpec::CharacterClass& character_class);
-
-std::ostream& operator<<(std::ostream& out,
- const PasswordRequirementsSpec& spec);
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_PRINTER_H_
diff --git a/chromium/components/autofill/core/browser/payments/OWNERS b/chromium/components/autofill/core/browser/payments/OWNERS
new file mode 100644
index 00000000000..c3fbe351b77
--- /dev/null
+++ b/chromium/components/autofill/core/browser/payments/OWNERS
@@ -0,0 +1 @@
+jsaul@google.com
diff --git a/chromium/components/autofill/core/browser/account_info_getter.h b/chromium/components/autofill/core/browser/payments/account_info_getter.h
index 44fa238ebec..42bf2fe3fbb 100644
--- a/chromium/components/autofill/core/browser/account_info_getter.h
+++ b/chromium/components/autofill/core/browser/payments/account_info_getter.h
@@ -2,8 +2,8 @@
// 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_ACCOUNT_INFO_GETTER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_ACCOUNT_INFO_GETTER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_ACCOUNT_INFO_GETTER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_ACCOUNT_INFO_GETTER_H_
#include <string>
@@ -30,4 +30,4 @@ class AccountInfoGetter {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_ACCOUNT_INFO_GETTER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_ACCOUNT_INFO_GETTER_H_
diff --git a/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc b/chromium/components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.cc
index fe4a4be83f1..aadf087dd49 100644
--- a/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.cc
@@ -2,8 +2,9 @@
// 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/autofill_credit_card_filling_infobar_delegate_mobile.h"
+#include "components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.h"
+#include "build/build_config.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
diff --git a/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h b/chromium/components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.h
index c7b8172a5c3..721af6e2491 100644
--- a/chromium/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h
+++ b/chromium/components/autofill/core/browser/payments/autofill_credit_card_filling_infobar_delegate_mobile.h
@@ -2,8 +2,8 @@
// 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_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
#include <memory>
@@ -67,4 +67,4 @@ class AutofillCreditCardFillingInfoBarDelegateMobile
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.cc
index 22fc50b9595..dda1712233f 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.cc
@@ -2,7 +2,7 @@
// 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/autofill_save_card_infobar_delegate_mobile.h"
+#include "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h"
#include <utility>
@@ -11,7 +11,7 @@
#include "base/values.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/credit_card.h"
-#include "components/autofill/core/browser/legal_message_line.h"
+#include "components/autofill/core/browser/payments/legal_message_line.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h b/chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h
index a99817a0ec5..62742f82744 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h
+++ b/chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h
@@ -2,8 +2,8 @@
// 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_AUTOFILL_SAVE_CARD_INFOBAR_DELEGATE_MOBILE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_SAVE_CARD_INFOBAR_DELEGATE_MOBILE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_SAVE_CARD_INFOBAR_DELEGATE_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_SAVE_CARD_INFOBAR_DELEGATE_MOBILE_H_
#include <memory>
@@ -12,7 +12,7 @@
#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/legal_message_line.h"
+#include "components/autofill/core/browser/payments/legal_message_line.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
class PrefService;
@@ -127,4 +127,4 @@ class AutofillSaveCardInfoBarDelegateMobile : public ConfirmInfoBarDelegate {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_SAVE_CARD_INFOBAR_DELEGATE_MOBILE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_SAVE_CARD_INFOBAR_DELEGATE_MOBILE_H_
diff --git a/chromium/components/autofill/core/browser/autofill_save_card_infobar_mobile.h b/chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_mobile.h
index 995bc7d9e08..969131b3a1e 100644
--- a/chromium/components/autofill/core/browser/autofill_save_card_infobar_mobile.h
+++ b/chromium/components/autofill/core/browser/payments/autofill_save_card_infobar_mobile.h
@@ -2,8 +2,8 @@
// 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_AUTOFILL_SAVE_CARD_INFOBAR_MOBILE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_SAVE_CARD_INFOBAR_MOBILE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_SAVE_CARD_INFOBAR_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_SAVE_CARD_INFOBAR_MOBILE_H_
#include <memory>
@@ -21,4 +21,4 @@ std::unique_ptr<infobars::InfoBar> CreateSaveCardInfoBarMobile(
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_SAVE_CARD_INFOBAR_MOBILE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_SAVE_CARD_INFOBAR_MOBILE_H_
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc b/chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller.cc
index 7ad8b87e824..576d1bbf07b 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
+++ b/chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller.cc
@@ -2,7 +2,7 @@
// 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/autofill_wallet_data_type_controller.h"
+#include "components/autofill/core/browser/payments/autofill_wallet_data_type_controller.h"
#include <utility>
@@ -21,8 +21,8 @@ namespace browser_sync {
AutofillWalletDataTypeController::AutofillWalletDataTypeController(
syncer::ModelType type,
- scoped_refptr<base::SingleThreadTaskRunner> db_thread,
- const base::Closure& dump_stack,
+ scoped_refptr<base::SequencedTaskRunner> db_thread,
+ const base::RepeatingClosure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
const PersonalDataManagerProvider& pdm_provider,
@@ -56,10 +56,8 @@ bool AutofillWalletDataTypeController::StartModels() {
DCHECK(CalledOnValidThread());
DCHECK_EQ(state(), MODEL_STARTING);
- if (!IsEnabled()) {
- DisableForPolicy();
+ if (!IsEnabled())
return false;
- }
if (!web_data_service_)
return false;
@@ -69,8 +67,8 @@ bool AutofillWalletDataTypeController::StartModels() {
if (!callback_registered_) {
web_data_service_->RegisterDBLoadedCallback(
- base::Bind(&AutofillWalletDataTypeController::OnModelLoaded,
- base::AsWeakPtr(this)));
+ base::BindRepeating(&AutofillWalletDataTypeController::OnModelLoaded,
+ base::AsWeakPtr(this)));
callback_registered_ = true;
}
@@ -123,13 +121,7 @@ void AutofillWalletDataTypeController::OnUserPrefChanged() {
return; // No change to sync state.
currently_enabled_ = new_enabled;
- if (currently_enabled_) {
- // The preference was just enabled. Trigger a reconfiguration. This will do
- // nothing if the type isn't preferred.
- sync_service()->ReenableDatatype(type());
- } else {
- DisableForPolicy();
- }
+ sync_service()->ReadyForStartChanged(type());
}
bool AutofillWalletDataTypeController::IsEnabled() {
@@ -141,12 +133,5 @@ bool AutofillWalletDataTypeController::IsEnabled() {
sync_client()->GetPrefService()->GetBoolean(
autofill::prefs::kAutofillCreditCardEnabled);
}
-void AutofillWalletDataTypeController::DisableForPolicy() {
- if (state() != NOT_RUNNING && state() != STOPPING) {
- CreateErrorHandler()->OnUnrecoverableError(
- syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_POLICY_ERROR,
- "Wallet syncing is disabled by policy.", type()));
- }
-}
} // namespace browser_sync
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h b/chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller.h
index be0e0fff83a..e6a1b54381c 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller.h
+++ b/chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller.h
@@ -2,12 +2,12 @@
// 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_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
#include "base/callback.h"
#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
+#include "base/sequenced_task_runner.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync/driver/async_directory_type_controller.h"
@@ -34,29 +34,26 @@ class AutofillWalletDataTypeController
// |dump_stack| is called when an unrecoverable error occurs.
AutofillWalletDataTypeController(
syncer::ModelType type,
- scoped_refptr<base::SingleThreadTaskRunner> db_thread,
- const base::Closure& dump_stack,
+ scoped_refptr<base::SequencedTaskRunner> db_thread,
+ const base::RepeatingClosure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
const PersonalDataManagerProvider& pdm_provider,
const scoped_refptr<autofill::AutofillWebDataService>& web_data_service);
~AutofillWalletDataTypeController() override;
- private:
// AsyncDirectoryTypeController implementation.
bool StartModels() override;
void StopModels() override;
bool ReadyForStart() const override;
+ private:
// Callback for changes to the autofill pref.
void OnUserPrefChanged();
// Returns true if the prefs are set such that wallet sync should be enabled.
bool IsEnabled();
- // Report an error (which will stop the datatype asynchronously).
- void DisableForPolicy();
-
// Callback that allows accessing PersonalDataManager lazily.
const PersonalDataManagerProvider pdm_provider_;
@@ -78,4 +75,4 @@ class AutofillWalletDataTypeController
} // namespace browser_sync
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc b/chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller_unittest.cc
index c8a98aff248..40d771670df 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_data_type_controller_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/autofill_wallet_data_type_controller_unittest.cc
@@ -2,7 +2,7 @@
// 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/autofill_wallet_data_type_controller.h"
+#include "components/autofill/core/browser/payments/autofill_wallet_data_type_controller.h"
#include <memory>
@@ -24,7 +24,7 @@
#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_service.h"
+#include "components/sync/driver/mock_sync_service.h"
#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/fake_syncable_service.h"
@@ -47,7 +47,7 @@ class FakeWebDataService : public AutofillWebDataService {
const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner)
: AutofillWebDataService(ui_task_runner, db_task_runner),
is_database_loaded_(false),
- db_loaded_callback_(base::Callback<void(void)>()) {}
+ db_loaded_callback_(base::RepeatingCallback<void(void)>()) {}
// Mark the database as loaded and send out the appropriate notification.
void LoadDatabase() {
@@ -57,14 +57,17 @@ class FakeWebDataService : public AutofillWebDataService {
db_loaded_callback_.Run();
// Clear the callback here or the WDS and DTC will have refs to each other
// and create a memory leak.
- db_loaded_callback_ = base::Callback<void(void)>();
+ // TODO(crbug.com/941530): Solve this with a OnceCallback. Note that
+ // RegisterDBLoadedCallback overrides other functions that still use
+ // base::[Repeating]Callbacks, so it would affect non-Autofill code.
+ db_loaded_callback_ = base::RepeatingCallback<void(void)>();
}
}
bool IsDatabaseLoaded() override { return is_database_loaded_; }
void RegisterDBLoadedCallback(
- const base::Callback<void(void)>& callback) override {
+ const base::RepeatingCallback<void(void)>& callback) override {
db_loaded_callback_ = callback;
}
@@ -72,14 +75,17 @@ class FakeWebDataService : public AutofillWebDataService {
~FakeWebDataService() override {}
bool is_database_loaded_;
- base::Callback<void(void)> db_loaded_callback_;
+ base::RepeatingCallback<void(void)> db_loaded_callback_;
DISALLOW_COPY_AND_ASSIGN(FakeWebDataService);
};
class AutofillWalletDataTypeControllerTest : public testing::Test {
public:
- AutofillWalletDataTypeControllerTest() : last_type_(syncer::UNSPECIFIED) {}
+ AutofillWalletDataTypeControllerTest() : last_type_(syncer::UNSPECIFIED) {
+ ON_CALL(sync_service_, GetUserShare()).WillByDefault(Return(&user_share_));
+ }
+
~AutofillWalletDataTypeControllerTest() override {}
void SetUp() override {
@@ -97,7 +103,7 @@ class AutofillWalletDataTypeControllerTest : public testing::Test {
base::ThreadTaskRunnerHandle::Get());
autofill_wallet_dtc_ = std::make_unique<AutofillWalletDataTypeController>(
syncer::AUTOFILL_WALLET_DATA, base::ThreadTaskRunnerHandle::Get(),
- base::DoNothing(), &sync_service_, &sync_client_,
+ /*dump_stack=*/base::DoNothing(), &sync_service_, &sync_client_,
AutofillWalletDataTypeController::PersonalDataManagerProvider(),
web_data_service_);
@@ -120,18 +126,21 @@ class AutofillWalletDataTypeControllerTest : public testing::Test {
syncer::AUTOFILL_WALLET_DATA)));
}
- void Start() {
+ bool Start() {
autofill_wallet_dtc_->LoadModels(
syncer::ConfigureContext(),
- base::Bind(&AutofillWalletDataTypeControllerTest::OnLoadFinished,
- base::Unretained(this)));
+ base::BindRepeating(
+ &AutofillWalletDataTypeControllerTest::OnLoadFinished,
+ base::Unretained(this)));
base::RunLoop().RunUntilIdle();
if (autofill_wallet_dtc_->state() !=
- syncer::DataTypeController::MODEL_LOADED)
- return;
- autofill_wallet_dtc_->StartAssociating(base::Bind(
+ syncer::DataTypeController::MODEL_LOADED) {
+ return false;
+ }
+ autofill_wallet_dtc_->StartAssociating(base::BindRepeating(
&syncer::StartCallbackMock::Run, base::Unretained(&start_callback_)));
base::RunLoop().RunUntilIdle();
+ return true;
}
void OnLoadFinished(syncer::ModelType type, const syncer::SyncError& error) {
@@ -141,7 +150,8 @@ class AutofillWalletDataTypeControllerTest : public testing::Test {
base::test::ScopedTaskEnvironment task_environment_;
TestingPrefServiceSimple prefs_;
- syncer::FakeSyncService sync_service_;
+ syncer::UserShare user_share_;
+ testing::NiceMock<syncer::MockSyncService> sync_service_;
syncer::StartCallbackMock start_callback_;
syncer::FakeSyncableService syncable_service_;
std::unique_ptr<AutofillWalletDataTypeController> autofill_wallet_dtc_;
@@ -179,10 +189,13 @@ 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_);
+
+ EXPECT_CALL(sync_service_,
+ ReadyForStartChanged(syncer::AUTOFILL_WALLET_DATA));
autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, false);
autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, true);
+ EXPECT_FALSE(autofill_wallet_dtc_->ReadyForStart());
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(last_error_.IsSet());
}
TEST_F(AutofillWalletDataTypeControllerTest,
@@ -198,10 +211,13 @@ 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_);
+
+ EXPECT_CALL(sync_service_,
+ ReadyForStartChanged(syncer::AUTOFILL_WALLET_DATA));
autofill::prefs::SetPaymentsIntegrationEnabled(&prefs_, true);
autofill::prefs::SetCreditCardAutofillEnabled(&prefs_, false);
+ EXPECT_FALSE(autofill_wallet_dtc_->ReadyForStart());
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(last_error_.IsSet());
}
TEST_F(AutofillWalletDataTypeControllerTest,
@@ -214,7 +230,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
autofill_wallet_dtc_->state());
Start();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(last_error_.IsSet());
+ // OnLoadFinished() should not have been called.
+ EXPECT_EQ(syncer::UNSPECIFIED, last_type_);
}
TEST_F(AutofillWalletDataTypeControllerTest,
@@ -227,7 +244,8 @@ TEST_F(AutofillWalletDataTypeControllerTest,
autofill_wallet_dtc_->state());
Start();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(last_error_.IsSet());
+ // OnLoadFinished() should not have been called.
+ EXPECT_EQ(syncer::UNSPECIFIED, last_type_);
}
} // namespace
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_model_type_controller.cc b/chromium/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.cc
index e725f1e87c9..c415ccfbc40 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_model_type_controller.cc
+++ b/chromium/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.cc
@@ -2,7 +2,7 @@
// 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/autofill_wallet_model_type_controller.h"
+#include "components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h"
#include <utility>
@@ -10,7 +10,9 @@
#include "base/bind_helpers.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_service.h"
+#include "components/sync/driver/sync_auth_util.h"
#include "components/sync/driver/sync_service.h"
+#include "google_apis/gaia/google_service_auth_error.h"
namespace browser_sync {
@@ -24,8 +26,10 @@ AutofillWalletModelTypeController::AutofillWalletModelTypeController(
sync_service_(sync_service) {
DCHECK(type == syncer::AUTOFILL_WALLET_DATA ||
type == syncer::AUTOFILL_WALLET_METADATA);
- currently_enabled_ = IsEnabled();
SubscribeToPrefChanges();
+ // TODO(crbug.com/906995): remove this observing mechanism once all sync
+ // datatypes are stopped by ProfileSyncService, when sync is paused.
+ sync_service_->AddObserver(this);
}
AutofillWalletModelTypeController::AutofillWalletModelTypeController(
@@ -41,36 +45,45 @@ AutofillWalletModelTypeController::AutofillWalletModelTypeController(
sync_service_(sync_service) {
DCHECK(type == syncer::AUTOFILL_WALLET_DATA ||
type == syncer::AUTOFILL_WALLET_METADATA);
- currently_enabled_ = IsEnabled();
SubscribeToPrefChanges();
+ // TODO(crbug.com/906995): remove this observing mechanism once all sync
+ // datatypes are stopped by ProfileSyncService, when sync is paused.
+ sync_service_->AddObserver(this);
}
-AutofillWalletModelTypeController::~AutofillWalletModelTypeController() {}
-
-bool AutofillWalletModelTypeController::ReadyForStart() const {
- DCHECK(CalledOnValidThread());
- return currently_enabled_;
+AutofillWalletModelTypeController::~AutofillWalletModelTypeController() {
+ sync_service_->RemoveObserver(this);
}
-void AutofillWalletModelTypeController::OnUserPrefChanged() {
+void AutofillWalletModelTypeController::Stop(
+ syncer::ShutdownReason shutdown_reason,
+ StopCallback callback) {
DCHECK(CalledOnValidThread());
-
- bool newly_enabled = IsEnabled();
- if (currently_enabled_ == newly_enabled) {
- return; // No change to sync state.
+ switch (shutdown_reason) {
+ case syncer::STOP_SYNC:
+ // Special case: For AUTOFILL_WALLET_DATA and AUTOFILL_WALLET_METADATA, we
+ // want to clear all data even when Sync is stopped temporarily.
+ shutdown_reason = syncer::DISABLE_SYNC;
+ break;
+ case syncer::DISABLE_SYNC:
+ case syncer::BROWSER_SHUTDOWN:
+ break;
}
-
- currently_enabled_ = newly_enabled;
- sync_service_->ReadyForStartChanged(type());
+ ModelTypeController::Stop(shutdown_reason, std::move(callback));
}
-bool AutofillWalletModelTypeController::IsEnabled() const {
+bool AutofillWalletModelTypeController::ReadyForStart() const {
DCHECK(CalledOnValidThread());
-
- // Require two user-visible prefs to be enabled to sync Wallet data/metadata.
return pref_service_->GetBoolean(
autofill::prefs::kAutofillWalletImportEnabled) &&
- pref_service_->GetBoolean(autofill::prefs::kAutofillCreditCardEnabled);
+ pref_service_->GetBoolean(
+ autofill::prefs::kAutofillCreditCardEnabled) &&
+ !syncer::IsWebSignout(sync_service_->GetAuthError());
+}
+
+void AutofillWalletModelTypeController::OnUserPrefChanged() {
+ DCHECK(CalledOnValidThread());
+ sync_service_->ReadyForStartChanged(type());
}
void AutofillWalletModelTypeController::SubscribeToPrefChanges() {
@@ -85,4 +98,10 @@ void AutofillWalletModelTypeController::SubscribeToPrefChanges() {
base::Unretained(this)));
}
+void AutofillWalletModelTypeController::OnStateChanged(
+ syncer::SyncService* sync) {
+ DCHECK(CalledOnValidThread());
+ sync_service_->ReadyForStartChanged(type());
+}
+
} // namespace browser_sync
diff --git a/chromium/components/autofill/core/browser/autofill_wallet_model_type_controller.h b/chromium/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h
index 1f9fcb50815..cee6054e828 100644
--- a/chromium/components/autofill/core/browser/autofill_wallet_model_type_controller.h
+++ b/chromium/components/autofill/core/browser/payments/autofill_wallet_model_type_controller.h
@@ -2,8 +2,8 @@
// 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_AUTOFILL_WALLET_MODEL_TYPE_CONTROLLER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_MODEL_TYPE_CONTROLLER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_WALLET_MODEL_TYPE_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_WALLET_MODEL_TYPE_CONTROLLER_H_
#include <memory>
#include <string>
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync/driver/model_type_controller.h"
+#include "components/sync/driver/sync_service_observer.h"
class PrefService;
@@ -21,7 +22,8 @@ class SyncService;
namespace browser_sync {
// Controls syncing of AUTOFILL_WALLET_DATA and AUTOFILL_WALLET_METADATA.
-class AutofillWalletModelTypeController : public syncer::ModelTypeController {
+class AutofillWalletModelTypeController : public syncer::ModelTypeController,
+ public syncer::SyncServiceObserver {
public:
// The delegates and |sync_client| must not be null. Furthermore,
// |sync_client| must outlive this object.
@@ -39,8 +41,13 @@ class AutofillWalletModelTypeController : public syncer::ModelTypeController {
~AutofillWalletModelTypeController() override;
// DataTypeController overrides.
+ void Stop(syncer::ShutdownReason shutdown_reason,
+ StopCallback callback) override;
bool ReadyForStart() const override;
+ // syncer::SyncServiceObserver implementation.
+ void OnStateChanged(syncer::SyncService* sync) override;
+
private:
// Callback for changes to the autofill pref.
void OnUserPrefChanged();
@@ -53,11 +60,9 @@ class AutofillWalletModelTypeController : public syncer::ModelTypeController {
PrefChangeRegistrar pref_registrar_;
- bool currently_enabled_;
-
DISALLOW_COPY_AND_ASSIGN(AutofillWalletModelTypeController);
};
} // namespace browser_sync
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_WALLET_MODEL_TYPE_CONTROLLER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_AUTOFILL_WALLET_MODEL_TYPE_CONTROLLER_H_
diff --git a/chromium/components/autofill/core/browser/card_unmask_delegate.cc b/chromium/components/autofill/core/browser/payments/card_unmask_delegate.cc
index f22bbb1ce77..82d06ecd0ac 100644
--- a/chromium/components/autofill/core/browser/card_unmask_delegate.cc
+++ b/chromium/components/autofill/core/browser/payments/card_unmask_delegate.cc
@@ -2,7 +2,7 @@
// 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/card_unmask_delegate.h"
+#include "components/autofill/core/browser/payments/card_unmask_delegate.h"
namespace autofill {
diff --git a/chromium/components/autofill/core/browser/card_unmask_delegate.h b/chromium/components/autofill/core/browser/payments/card_unmask_delegate.h
index 232a348d2ad..729e5a34cc7 100644
--- a/chromium/components/autofill/core/browser/card_unmask_delegate.h
+++ b/chromium/components/autofill/core/browser/payments/card_unmask_delegate.h
@@ -2,8 +2,8 @@
// 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_CARD_UNMASK_DELEGATE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_CARD_UNMASK_DELEGATE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CARD_UNMASK_DELEGATE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CARD_UNMASK_DELEGATE_H_
#include <string>
@@ -41,4 +41,4 @@ class CardUnmaskDelegate {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CARD_UNMASK_DELEGATE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CARD_UNMASK_DELEGATE_H_
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager.cc b/chromium/components/autofill/core/browser/payments/credit_card_save_manager.cc
index 910d5e02fd6..e35c805e3eb 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager.cc
+++ b/chromium/components/autofill/core/browser/payments/credit_card_save_manager.cc
@@ -2,7 +2,7 @@
// 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_manager.h"
+#include "components/autofill/core/browser/payments/credit_card_save_manager.h"
#include <stddef.h>
#include <stdint.h>
@@ -33,15 +33,16 @@
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/form_structure.h"
-#include "components/autofill/core/browser/legacy_strike_database.h"
+#include "components/autofill/core/browser/payments/legacy_strike_database.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/payments/payments_util.h"
+#include "components/autofill/core/browser/payments/strike_database.h"
#include "components/autofill/core/browser/personal_data_manager.h"
-#include "components/autofill/core/browser/strike_database.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_constants.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_util.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "url/gurl.h"
@@ -101,11 +102,13 @@ CreditCardSaveManager::CreditCardSaveManager(
CreditCardSaveManager::~CreditCardSaveManager() {}
void CreditCardSaveManager::AttemptToOfferCardLocalSave(
+ bool from_dynamic_change_form,
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;
+ from_dynamic_change_form_ = from_dynamic_change_form;
// Query the Autofill StrikeDatabase on if we should pop up the
// offer-to-save prompt for this card.
@@ -130,6 +133,7 @@ void CreditCardSaveManager::AttemptToOfferCardLocalSave(
void CreditCardSaveManager::AttemptToOfferCardUploadSave(
const FormStructure& submitted_form,
+ bool from_dynamic_change_form,
bool has_non_focusable_field,
const CreditCard& card,
const bool uploading_local_card) {
@@ -158,6 +162,7 @@ void CreditCardSaveManager::AttemptToOfferCardUploadSave(
found_cvc_value_in_non_cvc_field_ = false;
has_non_focusable_field_ = has_non_focusable_field;
+ from_dynamic_change_form_ = from_dynamic_change_form;
for (const auto& field : submitted_form) {
const bool is_valid_cvc = IsValidCreditCardSecurityCode(
@@ -187,7 +192,10 @@ void CreditCardSaveManager::AttemptToOfferCardUploadSave(
upload_decision_metrics_ |=
AutofillMetrics::UPLOAD_OFFERED_FROM_NON_FOCUSABLE_FIELD;
}
-
+ if (submitted_form.value_from_dynamic_change_form()) {
+ upload_decision_metrics_ |=
+ AutofillMetrics::UPLOAD_OFFERED_FROM_DYNAMIC_CHANGE_FORM;
+ }
if (upload_request_.cvc.empty()) {
// Apply the CVC decision to |upload_decision_metrics_| to denote a problem
// was found.
@@ -293,7 +301,8 @@ bool CreditCardSaveManager::IsCreditCardUploadEnabled() {
#endif // defined(OS_IOS)
return ::autofill::IsCreditCardUploadEnabled(
client_->GetPrefs(), client_->GetSyncService(),
- personal_data_manager_->GetAccountInfoForPaymentsServer().email);
+ personal_data_manager_->GetAccountInfoForPaymentsServer().email,
+ personal_data_manager_->GetSyncSigninState());
}
bool CreditCardSaveManager::IsUploadEnabledForNetwork(
@@ -444,8 +453,12 @@ void CreditCardSaveManager::OnDidGetUploadDetails(
features::kAutofillDoNotUploadSaveUnsupportedCards) &&
!supported_card_bin_ranges.empty() &&
!IsCreditCardSupported(supported_card_bin_ranges)) {
- AttemptToOfferCardLocalSave(has_non_focusable_field_,
- upload_request_.card);
+ // Attempt local card save if card not already saved.
+ if (!uploading_local_card_) {
+ AttemptToOfferCardLocalSave(from_dynamic_change_form_,
+ has_non_focusable_field_,
+ upload_request_.card);
+ }
upload_decision_metrics_ |=
AutofillMetrics::UPLOAD_NOT_OFFERED_UNSUPPORTED_BIN_RANGE;
LogCardUploadDecisions(upload_decision_metrics_);
@@ -484,7 +497,8 @@ void CreditCardSaveManager::OnDidGetUploadDetails(
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(has_non_focusable_field_,
+ AttemptToOfferCardLocalSave(from_dynamic_change_form_,
+ has_non_focusable_field_,
upload_request_.card);
}
upload_decision_metrics_ |=
@@ -538,6 +552,7 @@ void CreditCardSaveManager::OfferCardUploadSave() {
client_->ConfirmSaveCreditCardToCloud(
upload_request_.card, std::move(legal_message_),
AutofillClient::SaveCreditCardOptions()
+ .with_from_dynamic_change_form(from_dynamic_change_form_)
.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(
@@ -802,8 +817,7 @@ int CreditCardSaveManager::GetDetectedValues() const {
// Payments account. Include a bit for existence of this account (NOT the id
// itself), as it will help determine if a new Payments customer might need to
// be created when save is accepted.
- if (payments::GetBillingCustomerId(personal_data_manager_,
- payments_client_->GetPrefService()) != 0) {
+ if (payments::GetBillingCustomerId(personal_data_manager_) != 0) {
detected_values |= DetectedValue::HAS_GOOGLE_PAYMENTS_ACCOUNT;
}
@@ -964,8 +978,8 @@ void CreditCardSaveManager::SendUploadCardRequest() {
if (observer_for_testing_)
observer_for_testing_->OnSentUploadCardRequest();
upload_request_.app_locale = app_locale_;
- upload_request_.billing_customer_number = payments::GetBillingCustomerId(
- personal_data_manager_, payments_client_->GetPrefService());
+ upload_request_.billing_customer_number =
+ payments::GetBillingCustomerId(personal_data_manager_);
AutofillMetrics::LogUploadAcceptedCardOriginMetric(
uploading_local_card_
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager.h b/chromium/components/autofill/core/browser/payments/credit_card_save_manager.h
index 5cffff6e8c9..3319c5fb6cb 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager.h
+++ b/chromium/components/autofill/core/browser/payments/credit_card_save_manager.h
@@ -2,8 +2,8 @@
// 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_CREDIT_CARD_SAVE_MANAGER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_MANAGER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_SAVE_MANAGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_SAVE_MANAGER_H_
#include <map>
#include <memory>
@@ -17,9 +17,9 @@
#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/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/credit_card_save_strike_database.h"
+#include "components/autofill/core/browser/payments/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"
@@ -97,15 +97,21 @@ class CreditCardSaveManager {
// Begins the process to offer local credit card save to the user.
// 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,
+ // If |from_dynamic_change_form| is true, the save is triggered by a dynamic
+ // change form.
+ void AttemptToOfferCardLocalSave(bool from_dynamic_change_form,
+ 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.
+ // offered for upload is already a local card on the device. If
+ // |from_dynamic_change_form| is true, the save is triggered by a dynamic
+ // change form.
void AttemptToOfferCardUploadSave(const FormStructure& submitted_form,
+ bool from_dynamic_change_form,
bool has_non_focusable_field,
const CreditCard& card,
const bool uploading_local_card);
@@ -335,6 +341,10 @@ class CreditCardSaveManager {
// |is_focusable| is false.
bool has_non_focusable_field_ = false;
+ // |from_dynamic_change_form_| is |true| values imported from dynamic change
+ // form.
+ bool from_dynamic_change_form_ = false;
+
// The origin of the top level frame from which a form is uploaded.
url::Origin pending_upload_request_origin_;
@@ -366,4 +376,4 @@ class CreditCardSaveManager {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_MANAGER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_SAVE_MANAGER_H_
diff --git a/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc b/chromium/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
index d4d246aaf5f..17fc2ea63da 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -2,7 +2,7 @@
// 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_manager.h"
+#include "components/autofill/core/browser/payments/credit_card_save_manager.h"
#include <stddef.h>
@@ -28,21 +28,23 @@
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
+#include "components/autofill/core/browser/payments/payments_customer_data.h"
+#include "components/autofill/core/browser/payments/test_credit_card_save_manager.h"
+#include "components/autofill/core/browser/payments/test_credit_card_save_strike_database.h"
+#include "components/autofill/core/browser/payments/test_legacy_strike_database.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/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/browser/test_autofill_manager.h"
-#include "components/autofill/core/browser/test_credit_card_save_manager.h"
-#include "components/autofill/core/browser/test_credit_card_save_strike_database.h"
#include "components/autofill/core/browser/test_form_data_importer.h"
-#include "components/autofill/core/browser/test_legacy_strike_database.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
@@ -127,7 +129,7 @@ class CreditCardSaveManagerTest : public testing::Test {
base::ThreadTaskRunnerHandle::Get());
autofill_driver_->SetURLRequestContext(request_context_.get());
payments_client_ = new payments::TestPaymentsClient(
- autofill_driver_->GetURLLoaderFactory(), autofill_client_.GetPrefs(),
+ autofill_driver_->GetURLLoaderFactory(),
autofill_client_.GetIdentityManager(), &personal_data_);
autofill_client_.set_test_payments_client(
std::unique_ptr<payments::TestPaymentsClient>(payments_client_));
@@ -183,19 +185,21 @@ class CreditCardSaveManagerTest : public testing::Test {
bool is_https,
bool use_month_type,
bool split_names = false,
- bool is_from_non_focusable_form = false) {
+ bool is_from_non_focusable_form = false,
+ bool is_google_host = false) {
form->name = ASCIIToUTF16("MyForm");
- if (is_https) {
- form->origin = GURL("https://myform.com/form.html");
- form->action = GURL("https://myform.com/submit.html");
- form->main_frame_origin =
- url::Origin::Create(GURL("https://myform_root.com/form.html"));
- } else {
- form->origin = GURL("http://myform.com/form.html");
- form->action = GURL("http://myform.com/submit.html");
- form->main_frame_origin =
- url::Origin::Create(GURL("http://myform_root.com/form.html"));
- }
+ base::string16 scheme =
+ is_https ? ASCIIToUTF16("https://") : ASCIIToUTF16("http://");
+ base::string16 host = is_google_host ? ASCIIToUTF16("pay.google.com")
+ : ASCIIToUTF16("myform.com");
+ base::string16 root_host = is_google_host ? ASCIIToUTF16("pay.google.com")
+ : ASCIIToUTF16("myform.root.com");
+ base::string16 form_path = ASCIIToUTF16("/form.html");
+ base::string16 submit_path = ASCIIToUTF16("/submit.html");
+ form->url = GURL(scheme + host + form_path);
+ form->action = GURL(scheme + host + submit_path);
+ form->main_frame_origin =
+ url::Origin::Create(GURL(scheme + root_host + form_path));
FormFieldData field;
if (split_names) {
@@ -666,7 +670,7 @@ TEST_F(CreditCardSaveManagerTest, LocalCreditCard_LastAndFirstName) {
// fields.
FormData credit_card_form;
credit_card_form.name = ASCIIToUTF16("MyForm");
- credit_card_form.origin = GURL("https://myform.com/form.html");
+ credit_card_form.url = GURL("https://myform.com/form.html");
credit_card_form.action = GURL("https://myform.com/submit.html");
credit_card_form.main_frame_origin =
url::Origin::Create(GURL("https://myform_root.com/form.html"));
@@ -996,7 +1000,7 @@ TEST_F(CreditCardSaveManagerTest, UploadCreditCard_LastAndFirstName) {
// fields.
FormData credit_card_form;
credit_card_form.name = ASCIIToUTF16("MyForm");
- credit_card_form.origin = GURL("https://myform.com/form.html");
+ credit_card_form.url = GURL("https://myform.com/form.html");
credit_card_form.action = GURL("https://myform.com/submit.html");
credit_card_form.main_frame_origin =
url::Origin::Create(GURL("https://myform_root.com/form.html"));
@@ -1273,7 +1277,7 @@ TEST_F(CreditCardSaveManagerTest, UploadCreditCard_MultipleCvcFields) {
// Set up our credit card form data.
FormData credit_card_form;
credit_card_form.name = ASCIIToUTF16("MyForm");
- credit_card_form.origin = GURL("https://myform.com/form.html");
+ credit_card_form.url = GURL("https://myform.com/form.html");
credit_card_form.action = GURL("https://myform.com/submit.html");
credit_card_form.main_frame_origin =
url::Origin::Create(GURL("http://myform_root.com/form.html"));
@@ -1328,7 +1332,7 @@ TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NoCvcFieldOnForm) {
// Set up our credit card form data. Note that CVC field is missing.
FormData credit_card_form;
credit_card_form.name = ASCIIToUTF16("MyForm");
- credit_card_form.origin = GURL("https://myform.com/form.html");
+ credit_card_form.url = GURL("https://myform.com/form.html");
credit_card_form.action = GURL("https://myform.com/submit.html");
credit_card_form.main_frame_origin =
url::Origin::Create(GURL("http://myform_root.com/form.html"));
@@ -1381,7 +1385,7 @@ TEST_F(CreditCardSaveManagerTest,
// Set up our credit card form data. Note that CVC field is missing.
FormData credit_card_form;
credit_card_form.name = ASCIIToUTF16("MyForm");
- credit_card_form.origin = GURL("https://myform.com/form.html");
+ credit_card_form.url = GURL("https://myform.com/form.html");
credit_card_form.action = GURL("https://myform.com/submit.html");
credit_card_form.main_frame_origin =
url::Origin::Create(GURL("http://myform_root.com/form.html"));
@@ -1437,7 +1441,7 @@ TEST_F(CreditCardSaveManagerTest,
// Set up our credit card form data. Note that CVC field is missing.
FormData credit_card_form;
credit_card_form.name = ASCIIToUTF16("MyForm");
- credit_card_form.origin = GURL("https://myform.com/form.html");
+ credit_card_form.url = GURL("https://myform.com/form.html");
credit_card_form.action = GURL("https://myform.com/submit.html");
credit_card_form.main_frame_origin =
url::Origin::Create(GURL("http://myform_root.com/form.html"));
@@ -1495,7 +1499,7 @@ TEST_F(CreditCardSaveManagerTest,
// Set up our credit card form data. Note that CVC field is missing.
FormData credit_card_form;
credit_card_form.name = ASCIIToUTF16("MyForm");
- credit_card_form.origin = GURL("https://myform.com/form.html");
+ credit_card_form.url = GURL("https://myform.com/form.html");
credit_card_form.action = GURL("https://myform.com/submit.html");
credit_card_form.main_frame_origin =
url::Origin::Create(GURL("http://myform_root.com/form.html"));
@@ -2254,6 +2258,75 @@ TEST_F(
CreditCardSaveManager::DetectedValue::USER_PROVIDED_NAME);
}
+TEST_F(CreditCardSaveManagerTest,
+ GoogleHostSite_ShouldNotOfferSaveIfUploadEnabled) {
+ // 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));
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*split_names=*/false, /*split_names=*/false,
+ /*is_from_non_focusable_form*/ false,
+ /*is_google_host*/ true);
+ 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");
+
+ base::HistogramTester histogram_tester;
+
+ // The credit card should neither be saved locally or uploaded.
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+
+ // Verify that no histogram entry was logged.
+ histogram_tester.ExpectTotalCount("Autofill.CardUploadDecisionMetric", 0);
+}
+
+TEST_F(CreditCardSaveManagerTest,
+ GoogleHostSite_ShouldOfferSaveIfUploadDisabled) {
+ 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));
+ ManuallyFillAddressForm("Flo", "Master", "77401", "US", &address_form);
+ FormSubmitted(address_form);
+ // Set up our credit card form data.
+ FormData credit_card_form;
+ CreateTestCreditCardFormData(&credit_card_form, /*is_https=*/true,
+ /*split_names=*/false, /*split_names=*/false,
+ /*is_from_non_focusable_form*/ false,
+ /*is_google_host*/ true);
+ 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");
+
+ base::HistogramTester histogram_tester;
+
+ // The credit card should be saved locally.
+ FormSubmitted(credit_card_form);
+ EXPECT_TRUE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+ EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
+}
+
TEST_F(
CreditCardSaveManagerTest,
UploadCreditCard_DoNotRequestCardholderNameIfNameExistsAndNoPaymentsCustomer) {
@@ -2301,10 +2374,10 @@ TEST_F(
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamEditableCardholderName);
- // Set the billing_customer_number Priority Preference to designate existence
- // of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
// Create, fill and submit an address form in order to establish a recent
// profile which can be selected for the upload request.
@@ -2349,10 +2422,10 @@ TEST_F(
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamEditableCardholderName);
- // Set the billing_customer_number Priority Preference to designate existence
- // of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
// Create, fill and submit an address form in order to establish a recent
// profile which can be selected for the upload request.
@@ -2514,10 +2587,11 @@ TEST_F(
// Verify the |credit_card_save_manager_| is requesting cardholder name.
EXPECT_TRUE(credit_card_save_manager_->should_request_name_from_user_);
- // Simulate a Chrome/Payments sync where billing_customer_number was newly
- // set.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Run through the form submit in exactly the same way (but now Chrome knows
// that the user is a Google Payments customer).
personal_data_.ClearCreditCards();
@@ -3340,10 +3414,10 @@ TEST_P(CreditCardSaveManagerFeatureParameterizedTest, DetectCountryCode) {
TEST_P(CreditCardSaveManagerFeatureParameterizedTest,
DetectHasGooglePaymentAccount) {
- // Set the billing_customer_number Priority Preference to designate existence
- // of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
// Set up our credit card form data.
FormData credit_card_form;
@@ -5535,6 +5609,40 @@ TEST_F(CreditCardSaveManagerTest, UploadSaveNotOfferedForUnsupportedCard) {
EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
}
+// Tests that if a card doesn't fall in any of the supported bin ranges, but is
+// already saved, then local save is not offered.
+TEST_F(CreditCardSaveManagerTest, LocalSaveNotOfferedForSavedUnsupportedCard) {
+ 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));
+
+ // Add a local credit card whose number matches what we will
+ // enter below.
+ CreditCard local_card;
+ test::SetCreditCardInfo(&local_card, "Flo Master", "5454545454545454",
+ NextMonth().c_str(), NextYear().c_str(), "1");
+ local_card.set_record_type(CreditCard::LOCAL_CARD);
+ personal_data_.AddCreditCard(local_card);
+
+ // 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 is already saved, local save should not be offered.
+ FormSubmitted(credit_card_form);
+ EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled());
+}
+
// Tests that if a card falls in one of the supported bin ranges, upload save
// is offered.
TEST_F(CreditCardSaveManagerTest, UploadSaveOfferedForSupportedCard) {
diff --git a/chromium/components/autofill/core/browser/credit_card_save_strike_database.cc b/chromium/components/autofill/core/browser/payments/credit_card_save_strike_database.cc
index 5df822f385e..cd0fd9e0a93 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/credit_card_save_strike_database.cc
@@ -2,7 +2,7 @@
// 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 "components/autofill/core/browser/payments/credit_card_save_strike_database.h"
#include "components/autofill/core/browser/proto/strike_data.pb.h"
diff --git a/chromium/components/autofill/core/browser/credit_card_save_strike_database.h b/chromium/components/autofill/core/browser/payments/credit_card_save_strike_database.h
index 537682256f1..fbe68217b74 100644
--- a/chromium/components/autofill/core/browser/credit_card_save_strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/credit_card_save_strike_database.h
@@ -2,13 +2,13 @@
// 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_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
#include <string>
-#include "components/autofill/core/browser/strike_database.h"
-#include "components/autofill/core/browser/strike_database_integrator_base.h"
+#include "components/autofill/core/browser/payments/strike_database.h"
+#include "components/autofill/core/browser/payments/strike_database_integrator_base.h"
namespace autofill {
@@ -27,4 +27,4 @@ class CreditCardSaveStrikeDatabase : public StrikeDatabaseIntegratorBase {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/payments/full_card_request.cc b/chromium/components/autofill/core/browser/payments/full_card_request.cc
index 9aa14cbf0a0..746db66cdf2 100644
--- a/chromium/components/autofill/core/browser/payments/full_card_request.cc
+++ b/chromium/components/autofill/core/browser/payments/full_card_request.cc
@@ -69,8 +69,7 @@ void FullCardRequest::GetFullCard(const CreditCard& card,
if (should_unmask_card_) {
payments_client_->Prepare();
request_->billing_customer_number = GetBillingCustomerId(
- personal_data_manager_, payments_client_->GetPrefService(),
- /*should_log_validity=*/true);
+ personal_data_manager_, /*should_log_validity=*/true);
}
ui_delegate_->ShowUnmaskPrompt(request_->card, reason,
diff --git a/chromium/components/autofill/core/browser/payments/full_card_request.h b/chromium/components/autofill/core/browser/payments/full_card_request.h
index 38779049166..661ddad98e7 100644
--- a/chromium/components/autofill/core/browser/payments/full_card_request.h
+++ b/chromium/components/autofill/core/browser/payments/full_card_request.h
@@ -13,7 +13,7 @@
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_client.h"
-#include "components/autofill/core/browser/card_unmask_delegate.h"
+#include "components/autofill/core/browser/payments/card_unmask_delegate.h"
#include "components/autofill/core/browser/payments/payments_client.h"
namespace autofill {
diff --git a/chromium/components/autofill/core/browser/payments/full_card_request_unittest.cc b/chromium/components/autofill/core/browser/payments/full_card_request_unittest.cc
index fc4486c4cc6..a1177a2bf64 100644
--- a/chromium/components/autofill/core/browser/payments/full_card_request_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/full_card_request_unittest.cc
@@ -18,10 +18,6 @@
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
-#include "components/autofill/core/common/autofill_prefs.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
-#include "components/prefs/testing_pref_service.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
@@ -77,14 +73,9 @@ class FullCardRequestTest : public testing::Test {
test_shared_loader_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)) {
- std::unique_ptr<TestingPrefServiceSimple> pref_service(
- new TestingPrefServiceSimple());
- pref_service->registry()->RegisterDoublePref(
- prefs::kAutofillBillingCustomerNumber, 0.0);
- autofill_client_.SetPrefs(std::move(pref_service));
payments_client_ = std::make_unique<PaymentsClient>(
- test_shared_loader_factory_, autofill_client_.GetPrefs(),
- autofill_client_.GetIdentityManager(), &personal_data_);
+ test_shared_loader_factory_, autofill_client_.GetIdentityManager(),
+ &personal_data_);
request_ = std::make_unique<FullCardRequest>(
&autofill_client_, payments_client_.get(), &personal_data_);
personal_data_.SetAccountInfoForPayments(
diff --git a/chromium/components/autofill/core/browser/legacy_strike_database.cc b/chromium/components/autofill/core/browser/payments/legacy_strike_database.cc
index d575b2e43ae..9baf216e59b 100644
--- a/chromium/components/autofill/core/browser/legacy_strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/legacy_strike_database.cc
@@ -2,7 +2,7 @@
// 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/legacy_strike_database.h"
+#include "components/autofill/core/browser/payments/legacy_strike_database.h"
#include <string>
#include <utility>
diff --git a/chromium/components/autofill/core/browser/legacy_strike_database.h b/chromium/components/autofill/core/browser/payments/legacy_strike_database.h
index c0aca236581..38e7c29f4ee 100644
--- a/chromium/components/autofill/core/browser/legacy_strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/legacy_strike_database.h
@@ -2,8 +2,8 @@
// 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_LEGACY_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_LEGACY_STRIKE_DATABASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LEGACY_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LEGACY_STRIKE_DATABASE_H_
#include <memory>
#include <string>
@@ -145,4 +145,4 @@ class LegacyStrikeDatabase : public KeyedService {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LEGACY_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LEGACY_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc b/chromium/components/autofill/core/browser/payments/legacy_strike_database_unittest.cc
index 44e60a4ae0c..cbcd36eb25b 100644
--- a/chromium/components/autofill/core/browser/legacy_strike_database_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/legacy_strike_database_unittest.cc
@@ -2,7 +2,7 @@
// 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/legacy_strike_database.h"
+#include "components/autofill/core/browser/payments/legacy_strike_database.h"
#include <utility>
#include <vector>
diff --git a/chromium/components/autofill/core/browser/legal_message_line.cc b/chromium/components/autofill/core/browser/payments/legal_message_line.cc
index dc28aebb703..b18bc273c41 100644
--- a/chromium/components/autofill/core/browser/legal_message_line.cc
+++ b/chromium/components/autofill/core/browser/payments/legal_message_line.cc
@@ -2,7 +2,7 @@
// 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/legal_message_line.h"
+#include "components/autofill/core/browser/payments/legal_message_line.h"
#include "base/i18n/message_formatter.h"
#include "base/logging.h"
@@ -78,63 +78,70 @@ LegalMessageLine::LegalMessageLine(const LegalMessageLine& other) = default;
LegalMessageLine::~LegalMessageLine() {}
// static
-bool LegalMessageLine::Parse(const base::DictionaryValue& legal_message,
+bool LegalMessageLine::Parse(const base::Value& legal_message,
LegalMessageLines* out,
bool escape_apostrophes) {
- const base::ListValue* lines_list = nullptr;
- if (legal_message.GetList("line", &lines_list)) {
+ DCHECK(legal_message.is_dict());
+ const base::Value* lines_list =
+ legal_message.FindKeyOfType("line", base::Value::Type::LIST);
+ if (lines_list) {
LegalMessageLines lines;
- lines.reserve(lines_list->GetSize());
- for (size_t i = 0; i < lines_list->GetSize(); ++i) {
+ lines.reserve(lines_list->GetList().size());
+ for (const base::Value& single_line : lines_list->GetList()) {
lines.emplace_back(LegalMessageLine());
- const base::DictionaryValue* single_line;
- if (!lines_list->GetDictionary(i, &single_line) ||
- !lines.back().ParseLine(*single_line, escape_apostrophes))
+ if (!single_line.is_dict() ||
+ !lines.back().ParseLine(single_line, escape_apostrophes))
return false;
}
out->swap(lines);
}
-
return true;
}
-bool LegalMessageLine::ParseLine(const base::DictionaryValue& line,
+bool LegalMessageLine::ParseLine(const base::Value& line,
bool escape_apostrophes) {
DCHECK(text_.empty());
DCHECK(links_.empty());
+ DCHECK(line.is_dict());
// |display_texts| elements are the strings that will be substituted for
// "{0}", "{1}", etc. in the template string.
std::vector<base::string16> display_texts;
// Process all the template parameters.
- const base::ListValue* template_parameters = nullptr;
- if (line.GetList("template_parameter", &template_parameters)) {
- display_texts.resize(template_parameters->GetSize());
- links_.reserve(template_parameters->GetSize());
-
- for (size_t parameter_index = 0;
- parameter_index < template_parameters->GetSize(); ++parameter_index) {
- const base::DictionaryValue* single_parameter;
- std::string url;
- if (!template_parameters->GetDictionary(parameter_index,
- &single_parameter) ||
- !single_parameter->GetString("display_text",
- &display_texts[parameter_index]) ||
- !single_parameter->GetString("url", &url))
+ const base::Value* template_parameters =
+ line.FindKeyOfType("template_parameter", base::Value::Type::LIST);
+ if (template_parameters) {
+ const base::Value::ListStorage& template_parameters_storage =
+ template_parameters->GetList();
+ display_texts.reserve(template_parameters_storage.size());
+ links_.reserve(template_parameters_storage.size());
+
+ for (const base::Value& parameter : template_parameters_storage) {
+ if (!parameter.is_dict())
+ return false;
+
+ const std::string* display_text = parameter.FindStringKey("display_text");
+ if (!display_text)
+ return false;
+
+ const std::string* url = parameter.FindStringKey("url");
+ if (!url)
return false;
- links_.emplace_back(0, 0, url);
+ display_texts.push_back(base::UTF8ToUTF16(*display_text));
+ links_.emplace_back(0, 0, *url);
}
}
// Read the template string. It's a small subset of the ICU message format
// syntax.
- base::string16 template_icu;
- if (!line.GetString("template", &template_icu))
+ const std::string* template_icu_utf8 = line.FindStringKey("template");
+ if (!template_icu_utf8)
return false;
+ base::string16 template_icu = base::UTF8ToUTF16(*template_icu_utf8);
if (escape_apostrophes) {
// The ICU standard counts "'{" as beginning an escaped string literal, even
// if there's no closing apostrophe. This fails legal message templates
diff --git a/chromium/components/autofill/core/browser/legal_message_line.h b/chromium/components/autofill/core/browser/payments/legal_message_line.h
index 141ea92dd70..4d9f2659be5 100644
--- a/chromium/components/autofill/core/browser/legal_message_line.h
+++ b/chromium/components/autofill/core/browser/payments/legal_message_line.h
@@ -2,8 +2,8 @@
// 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_LEGAL_MESSAGE_LINE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_LEGAL_MESSAGE_LINE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LEGAL_MESSAGE_LINE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LEGAL_MESSAGE_LINE_H_
#include <string>
#include <vector>
@@ -15,7 +15,7 @@
#include "url/gurl.h"
namespace base {
-class DictionaryValue;
+class Value;
}
namespace autofill {
@@ -68,7 +68,9 @@ class LegalMessageLine {
// text in MessageFormat, "'{0}" gets treated as a literal. To avoid
// situations like these, setting |escape_apostrophes| to true will escape
// all ASCII apostrophes by doubling them up.
- static bool Parse(const base::DictionaryValue& legal_message,
+ //
+ // |legal_message| must be a base::Value of type DICTIONARY.
+ static bool Parse(const base::Value& legal_message,
LegalMessageLines* out,
bool escape_apostrophes = false);
@@ -78,7 +80,7 @@ class LegalMessageLine {
private:
friend class TestLegalMessageLine;
- bool ParseLine(const base::DictionaryValue& line, bool escape_apostrophes);
+ bool ParseLine(const base::Value& line, bool escape_apostrophes);
base::string16 text_;
std::vector<Link> links_;
@@ -86,4 +88,4 @@ class LegalMessageLine {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LEGAL_MESSAGE_LINE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LEGAL_MESSAGE_LINE_H_
diff --git a/chromium/components/autofill/core/browser/legal_message_line_unittest.cc b/chromium/components/autofill/core/browser/payments/legal_message_line_unittest.cc
index 6a5c5ba8fd8..d5a10a1b5cc 100644
--- a/chromium/components/autofill/core/browser/legal_message_line_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/legal_message_line_unittest.cc
@@ -2,7 +2,7 @@
// 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/legal_message_line.h"
+#include "components/autofill/core/browser/payments/legal_message_line.h"
#include <memory>
#include <string>
@@ -103,15 +103,12 @@ 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::ReadDeprecated(GetParam().message_json));
+ base::Optional<base::Value> value(
+ base::JSONReader::Read(GetParam().message_json));
ASSERT_TRUE(value);
- base::DictionaryValue* dictionary = nullptr;
- EXPECT_TRUE(value->GetAsDictionary(&dictionary));
- ASSERT_TRUE(dictionary);
+ ASSERT_TRUE(value->is_dict());
LegalMessageLines actual_lines;
- LegalMessageLine::Parse(*dictionary, &actual_lines,
- GetParam().escape_apostrophes);
+ LegalMessageLine::Parse(*value, &actual_lines, GetParam().escape_apostrophes);
EXPECT_EQ(GetParam().expected_lines, actual_lines);
}
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager.cc b/chromium/components/autofill/core/browser/payments/local_card_migration_manager.cc
index f77d16d7bde..a9ce3821024 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager.cc
+++ b/chromium/components/autofill/core/browser/payments/local_card_migration_manager.cc
@@ -2,7 +2,7 @@
// 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_manager.h"
+#include "components/autofill/core/browser/payments/local_card_migration_manager.h"
#include <stddef.h>
@@ -22,6 +22,7 @@
#include "components/autofill/core/browser/payments/payments_util.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "services/identity/public/cpp/identity_manager.h"
@@ -190,38 +191,9 @@ void LocalCardMigrationManager::OnUserDeletedLocalCardViaMigrationDialog(
}
bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() {
- // Confirm that the user is signed in, syncing, and the proper experiment
- // flags are enabled.
- bool migration_experiment_enabled =
- features::GetLocalCardMigrationExperimentalFlag() !=
- features::LocalCardMigrationExperimentalFlag::kMigrationDisabled;
-
- // 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);
-
- AutofillSyncSigninState sync_state =
- personal_data_manager_->GetSyncSigninState();
-
- return migration_experiment_enabled && credit_card_upload_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)));
+ return ::autofill::IsCreditCardMigrationEnabled(
+ personal_data_manager_, client_->GetPrefs(), client_->GetSyncService(),
+ /*is_test_mode=*/observer_for_testing_);
}
void LocalCardMigrationManager::OnDidGetUploadDetails(
@@ -337,8 +309,8 @@ void LocalCardMigrationManager::SendMigrateLocalCardsRequest() {
observer_for_testing_->OnSentMigrateCardsRequest();
migration_request_.app_locale = app_locale_;
- migration_request_.billing_customer_number = payments::GetBillingCustomerId(
- personal_data_manager_, payments_client_->GetPrefService());
+ migration_request_.billing_customer_number =
+ payments::GetBillingCustomerId(personal_data_manager_);
payments_client_->MigrateCards(
migration_request_, migratable_credit_cards_,
base::BindOnce(&LocalCardMigrationManager::OnDidMigrateLocalCards,
@@ -390,8 +362,7 @@ int LocalCardMigrationManager::GetDetectedValues() const {
// Local card migration should ONLY be offered when the user already has a
// Google Payments account.
- DCHECK_NE(0, payments::GetBillingCustomerId(
- personal_data_manager_, payments_client_->GetPrefService()));
+ DCHECK_NE(0, payments::GetBillingCustomerId(personal_data_manager_));
detected_values |=
CreditCardSaveManager::DetectedValue::HAS_GOOGLE_PAYMENTS_ACCOUNT;
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager.h b/chromium/components/autofill/core/browser/payments/local_card_migration_manager.h
index 02365d324a1..9c12b4ec0b0 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager.h
+++ b/chromium/components/autofill/core/browser/payments/local_card_migration_manager.h
@@ -2,8 +2,8 @@
// 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_LOCAL_CARD_MIGRATION_MANAGER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_LOCAL_CARD_MIGRATION_MANAGER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_MANAGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_MANAGER_H_
#include <memory>
#include <string>
@@ -13,7 +13,7 @@
#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/local_card_migration_strike_database.h"
#include "components/autofill/core/browser/payments/payments_client.h"
namespace autofill {
@@ -222,4 +222,4 @@ class LocalCardMigrationManager {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LOCAL_CARD_MIGRATION_MANAGER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_MANAGER_H_
diff --git a/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc b/chromium/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
index 9e6e3a98e10..00b217d4483 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
@@ -2,7 +2,7 @@
// 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_manager.h"
+#include "components/autofill/core/browser/payments/local_card_migration_manager.h"
#include <stddef.h>
@@ -27,6 +27,9 @@
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
+#include "components/autofill/core/browser/payments/payments_customer_data.h"
+#include "components/autofill/core/browser/payments/test_credit_card_save_manager.h"
+#include "components/autofill/core/browser/payments/test_local_card_migration_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"
@@ -34,14 +37,13 @@
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/test_autofill_driver.h"
#include "components/autofill/core/browser/test_autofill_manager.h"
-#include "components/autofill/core/browser/test_credit_card_save_manager.h"
#include "components/autofill/core/browser/test_form_data_importer.h"
-#include "components/autofill/core/browser/test_local_card_migration_manager.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_clock.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
@@ -71,7 +73,7 @@ class LocalCardMigrationManagerTest : public testing::Test {
base::ThreadTaskRunnerHandle::Get());
autofill_driver_->SetURLRequestContext(request_context_.get());
payments_client_ = new payments::TestPaymentsClient(
- autofill_driver_->GetURLLoaderFactory(), autofill_client_.GetPrefs(),
+ autofill_driver_->GetURLLoaderFactory(),
autofill_client_.GetIdentityManager(), &personal_data_);
autofill_client_.set_test_payments_client(
std::unique_ptr<payments::TestPaymentsClient>(payments_client_));
@@ -188,10 +190,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -222,10 +225,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card (but it will not match what we will enter below).
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1", "guid1");
@@ -253,10 +257,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -300,10 +305,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -334,10 +340,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a masked server credit card whose |TypeAndLastFourDigits| matches what
// we will enter below.
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
@@ -384,10 +391,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a masked credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "a123");
@@ -427,10 +435,11 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_FeatureNotEnabled) {
scoped_feature_list_.InitAndDisableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -460,10 +469,10 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnlyWhenExpOff) {
// Disabled
{features::kAutofillEnableLocalCardMigrationForNonSyncUser});
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
// Mock Chrome Sync is disabled.
local_card_migration_manager_->ResetSyncState(
@@ -499,10 +508,10 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnlyWhenExpOn) {
// Disabled
{});
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
// Mock Chrome Sync is disabled.
local_card_migration_manager_->ResetSyncState(
@@ -561,10 +570,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a masked server card whose |TypeAndLastFourDigits| matches a local
// card.
CreditCard server_card(CreditCard::MASKED_SERVER_CARD, "a123");
@@ -599,10 +609,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a full server card whose number matches a local card.
CreditCard server_card(CreditCard::FULL_SERVER_CARD, "a123");
test::SetCreditCardInfo(&server_card, "Flo Master", "4111111111111111", "11",
@@ -632,10 +643,11 @@ TEST_F(LocalCardMigrationManagerTest, GetDetectedValues_AllWithCardHolderName) {
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -665,10 +677,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -697,10 +710,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -729,10 +743,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -763,10 +778,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -797,10 +813,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card. One migratable credit card will still trigger
// migration on settings page.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -827,10 +844,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card. One migratable credit card will still trigger
// migration on settings page.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -867,10 +885,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -899,10 +918,10 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
// Set that previously user rejected this prompt.
prefs::SetLocalCardMigrationPromptPreviouslyCancelled(
@@ -937,10 +956,11 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_MigrationSuccess) {
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card for migration.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1", "guid1");
@@ -979,10 +999,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card. One migratable credit card will still trigger
// migration on settings page.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -1023,10 +1044,11 @@ TEST_F(LocalCardMigrationManagerTest,
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillCreditCardLocalCardMigration);
- // Set the billing_customer_number Priority Preference to designate
- // existence of a Payments account.
- autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
- 12345);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card. One migratable credit card will still trigger
// migration on settings page.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -1068,8 +1090,11 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_ToggleIsChosen) {
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);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
local_card_migration_manager_->GetMigratableCreditCards();
autofill_client_.set_migration_card_selections(
@@ -1117,10 +1142,11 @@ TEST_F(LocalCardMigrationManagerTest,
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);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
+
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
@@ -1166,10 +1192,10 @@ TEST_F(LocalCardMigrationManagerTest,
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);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
// Add a masked server credit card whose |TypeAndLastFourDigits| matches what
// we will enter below.
@@ -1222,8 +1248,10 @@ TEST_F(LocalCardMigrationManagerTest,
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);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
local_card_migration_manager_->GetMigratableCreditCards();
// Only select one of the two cards.
@@ -1248,8 +1276,10 @@ TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_StrikeCountUMALogged) {
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);
+ // Set the billing_customer_number to designate existence of a Payments
+ // account.
+ personal_data_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
local_card_migration_manager_->GetMigratableCreditCards();
// Add 4 LocalCardMigration strikes.
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc b/chromium/components/autofill/core/browser/payments/local_card_migration_strike_database.cc
index 5c204950aa7..7cc649b6c58 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/local_card_migration_strike_database.cc
@@ -2,7 +2,7 @@
// 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 "components/autofill/core/browser/payments/local_card_migration_strike_database.h"
#include "components/autofill/core/browser/proto/strike_data.pb.h"
diff --git a/chromium/components/autofill/core/browser/local_card_migration_strike_database.h b/chromium/components/autofill/core/browser/payments/local_card_migration_strike_database.h
index 1124374313e..c63866dbd83 100644
--- a/chromium/components/autofill/core/browser/local_card_migration_strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/local_card_migration_strike_database.h
@@ -2,13 +2,13 @@
// 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_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
#include <string>
-#include "components/autofill/core/browser/strike_database.h"
-#include "components/autofill/core/browser/strike_database_integrator_base.h"
+#include "components/autofill/core/browser/payments/strike_database.h"
+#include "components/autofill/core/browser/payments/strike_database_integrator_base.h"
namespace autofill {
@@ -36,4 +36,4 @@ class LocalCardMigrationStrikeDatabase : public StrikeDatabaseIntegratorBase {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.cc b/chromium/components/autofill/core/browser/payments/payments_client.cc
index 3fda27d89e6..25fea378744 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_client.cc
@@ -13,20 +13,22 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
-#include "components/autofill/core/browser/account_info_getter.h"
#include "components/autofill/core/browser/autofill_data_model.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/credit_card.h"
-#include "components/autofill/core/browser/local_card_migration_manager.h"
+#include "components/autofill/core/browser/payments/account_info_getter.h"
+#include "components/autofill/core/browser/payments/local_card_migration_manager.h"
#include "components/autofill/core/browser/payments/payments_request.h"
#include "components/autofill/core/browser/payments/payments_service_url.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/variations/net/variations_http_headers.h"
#include "net/base/escape.h"
@@ -91,32 +93,6 @@ GURL GetRequestUrl(const std::string& path) {
return GetBaseSecureUrl().Resolve(path);
}
-// Tries to get the string |out_value| from the |dictionary| with the given
-// |key|.
-// Returns true if the string value was found, false otherwise.
-bool TryGetString(std::string key,
- base::Value& dictionary,
- std::string* out_value) {
- base::Value* str_ptr = dictionary.FindKey(key);
- if (str_ptr) {
- *out_value = str_ptr->GetString();
- }
- return str_ptr;
-}
-
-// Tries to get the string |out_value| from the |dictionary| with the given
-// |path|.
-// Returns true if the string value was found, false otherwise.
-bool TryGetStringByPath(std::initializer_list<base::StringPiece> path,
- base::Value& dictionary,
- std::string* out_value) {
- base::Value* str_ptr = dictionary.FindPath(path);
- if (str_ptr) {
- *out_value = str_ptr->GetString();
- }
- return str_ptr;
-}
-
base::Value BuildCustomerContextDictionary(int64_t external_customer_id) {
base::Value customer_context(base::Value::Type::DICTIONARY);
customer_context.SetKey("external_customer_id",
@@ -314,8 +290,9 @@ class UnmaskCardRequest : public PaymentsRequest {
return request_content;
}
- void ParseResponse(base::Value response) override {
- TryGetString("pan", response, &real_pan_);
+ void ParseResponse(const base::Value& response) override {
+ const auto* pan = response.FindStringKey("pan");
+ real_pan_ = pan ? *pan : std::string();
}
bool IsResponseComplete() override { return !real_pan_.empty(); }
@@ -331,6 +308,8 @@ class UnmaskCardRequest : public PaymentsRequest {
const std::string&)>
callback_;
std::string real_pan_;
+
+ DISALLOW_COPY_AND_ASSIGN(UnmaskCardRequest);
};
class GetUploadDetailsRequest : public PaymentsRequest {
@@ -434,25 +413,21 @@ class GetUploadDetailsRequest : public PaymentsRequest {
return request_content;
}
- void ParseResponse(base::Value response) override {
- std::string context_token_utf8;
- if (TryGetString("context_token", response, &context_token_utf8)) {
- context_token_ = base::UTF8ToUTF16(context_token_utf8);
- }
+ void ParseResponse(const base::Value& response) override {
+ const auto* context_token = response.FindStringKey("context_token");
+ context_token_ =
+ context_token ? base::UTF8ToUTF16(*context_token) : base::string16();
- base::Value* dictionary_value = response.FindKey("legal_message");
+ const base::Value* dictionary_value =
+ response.FindKeyOfType("legal_message", base::Value::Type::DICTIONARY);
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));
- }
- }
+ const auto* supported_card_bin_ranges_string =
+ response.FindStringKey("supported_card_bin_ranges_string");
+ supported_card_bin_ranges_ = ParseSupportedCardBinRangesString(
+ supported_card_bin_ranges_string ? *supported_card_bin_ranges_string
+ : base::EmptyString());
}
bool IsResponseComplete() override {
@@ -465,6 +440,35 @@ class GetUploadDetailsRequest : public PaymentsRequest {
}
private:
+ // Helper for ParseResponse(). Input format should be :"1234,30000-55555,765",
+ // where ranges are separated by commas and items separated with a dash means
+ // the start and ends of the range. Items without a dash have the same start
+ // and end (ex. 1234-1234)
+ std::vector<std::pair<int, int>> ParseSupportedCardBinRangesString(
+ const std::string& supported_card_bin_ranges_string) {
+ std::vector<std::pair<int, int>> supported_card_bin_ranges;
+ std::vector<std::string> range_strings =
+ base::SplitString(supported_card_bin_ranges_string, ",",
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+ for (std::string& range_string : range_strings) {
+ std::vector<std::string> range = base::SplitString(
+ range_string, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ DCHECK(range.size() <= 2);
+ int start;
+ base::StringToInt(range[0], &start);
+ if (range.size() == 1) {
+ supported_card_bin_ranges.push_back(std::make_pair(start, start));
+ } else {
+ int end;
+ base::StringToInt(range[1], &end);
+ DCHECK_LE(start, end);
+ supported_card_bin_ranges.push_back(std::make_pair(start, end));
+ }
+ }
+ return supported_card_bin_ranges;
+ }
+
const std::vector<AutofillProfile> addresses_;
const int detected_values_;
const std::vector<const char*> active_experiments_;
@@ -480,6 +484,8 @@ class GetUploadDetailsRequest : public PaymentsRequest {
std::vector<std::pair<int, int>> supported_card_bin_ranges_;
const int billable_service_number_;
PaymentsClient::UploadCardSource upload_card_source_;
+
+ DISALLOW_COPY_AND_ASSIGN(GetUploadDetailsRequest);
};
class UploadCardRequest : public PaymentsRequest {
@@ -575,8 +581,10 @@ class UploadCardRequest : public PaymentsRequest {
return request_content;
}
- void ParseResponse(base::Value response) override {
- TryGetString("credit_card_id", response, &server_id_);
+ void ParseResponse(const base::Value& response) override {
+ const std::string* credit_card_id =
+ response.FindStringKey("credit_card_id");
+ server_id_ = credit_card_id ? *credit_card_id : std::string();
}
bool IsResponseComplete() override { return true; }
@@ -592,6 +600,8 @@ class UploadCardRequest : public PaymentsRequest {
const std::string&)>
callback_;
std::string server_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(UploadCardRequest);
};
class MigrateCardsRequest : public PaymentsRequest {
@@ -666,26 +676,27 @@ class MigrateCardsRequest : public PaymentsRequest {
return request_content;
}
- void ParseResponse(base::Value response) override {
- base::Value* list_ptr = response.FindKey("save_result");
- if (!list_ptr || !list_ptr->is_list())
+ void ParseResponse(const base::Value& response) override {
+ const auto* found_list =
+ response.FindKeyOfType("save_result", base::Value::Type::LIST);
+ if (!found_list)
return;
+
save_result_ =
std::make_unique<std::unordered_map<std::string, std::string>>();
-
- for (base::Value& result : list_ptr->GetList()) {
+ for (const base::Value& result : found_list->GetList()) {
if (result.is_dict()) {
- std::string unique_id;
- TryGetString("unique_id", result, &unique_id);
-
- std::string save_result;
- TryGetString("status", result, &save_result);
-
- save_result_->insert(std::make_pair(unique_id, save_result));
+ const std::string* unique_id = result.FindStringKey("unique_id");
+ const std::string* status = result.FindStringKey("status");
+ save_result_->insert(
+ std::make_pair(unique_id ? *unique_id : std::string(),
+ status ? *status : std::string()));
}
}
- TryGetString("value_prop_display_text", response, &display_text_);
+ const std::string* display_text =
+ response.FindStringKey("value_prop_display_text");
+ display_text_ = display_text ? *display_text : std::string();
}
bool IsResponseComplete() override {
@@ -720,6 +731,8 @@ class MigrateCardsRequest : public PaymentsRequest {
MigrateCardsCallback callback_;
std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_;
std::string display_text_;
+
+ DISALLOW_COPY_AND_ASSIGN(MigrateCardsRequest);
};
} // namespace
@@ -744,12 +757,10 @@ PaymentsClient::MigrationRequestDetails::~MigrationRequestDetails() {}
PaymentsClient::PaymentsClient(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- PrefService* pref_service,
identity::IdentityManager* identity_manager,
AccountInfoGetter* account_info_getter,
bool is_off_the_record)
: url_loader_factory_(url_loader_factory),
- pref_service_(pref_service),
identity_manager_(identity_manager),
account_info_getter_(account_info_getter),
is_off_the_record_(is_off_the_record),
@@ -763,10 +774,6 @@ void PaymentsClient::Prepare() {
StartTokenFetch(false);
}
-PrefService* PaymentsClient::GetPrefService() const {
- return pref_service_;
-}
-
void PaymentsClient::UnmaskCard(
const PaymentsClient::UnmaskRequestDetails& request_details,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
@@ -885,7 +892,6 @@ void PaymentsClient::OnSimpleLoaderComplete(
void PaymentsClient::OnSimpleLoaderCompleteInternal(int response_code,
const std::string& data) {
- base::Value response_dict(base::Value::Type::DICTIONARY);
VLOG(2) << "Got data: " << data;
AutofillClient::PaymentsRpcResult result = AutofillClient::SUCCESS;
@@ -894,13 +900,13 @@ 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::ReadDeprecated(data);
- if (message_value.get() && message_value->is_dict()) {
- response_dict =
- base::Value::FromUniquePtrValue(std::move(message_value));
- TryGetStringByPath({"error", "code"}, response_dict, &error_code);
- request_->ParseResponse(std::move(response_dict));
+ base::Optional<base::Value> message_value = base::JSONReader::Read(data);
+ if (message_value && message_value->is_dict()) {
+ const auto* found = message_value->FindPathOfType(
+ {"error", "code"}, base::Value::Type::STRING);
+ if (found)
+ error_code = found->GetString();
+ request_->ParseResponse(*message_value);
}
if (base::LowerCaseEqualsASCII(error_code, "internal"))
diff --git a/chromium/components/autofill/core/browser/payments/payments_client.h b/chromium/components/autofill/core/browser/payments/payments_client.h
index ad6c075aa75..9f6d6247949 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client.h
+++ b/chromium/components/autofill/core/browser/payments/payments_client.h
@@ -13,9 +13,8 @@
#include "base/memory/weak_ptr.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_profile.h"
-#include "components/autofill/core/browser/card_unmask_delegate.h"
#include "components/autofill/core/browser/credit_card.h"
-#include "components/prefs/pref_service.h"
+#include "components/autofill/core/browser/payments/card_unmask_delegate.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/access_token_fetcher.h"
#include "services/identity/public/cpp/access_token_info.h"
@@ -134,13 +133,11 @@ class PaymentsClient {
};
// |url_loader_factory| is reference counted so it has no lifetime or
- // ownership requirements. |pref_service| is used to get the registered
- // preference value, |identity_manager| and |account_info_getter|
- // must all outlive |this|. Either delegate might be nullptr.
- // |is_off_the_record| denotes incognito mode.
+ // ownership requirements. |identity_manager| and |account_info_getter| must
+ // all outlive |this|. Either delegate might be nullptr. |is_off_the_record|
+ // denotes incognito mode.
PaymentsClient(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- PrefService* const pref_service,
identity::IdentityManager* const identity_manager,
AccountInfoGetter* const account_info_getter,
bool is_off_the_record = false);
@@ -154,8 +151,6 @@ class PaymentsClient {
// accepted an upload prompt.
void Prepare();
- PrefService* GetPrefService() const;
-
// The user has attempted to unmask a card with the given cvc.
void UnmaskCard(const UnmaskRequestDetails& request_details,
base::OnceCallback<void(AutofillClient::PaymentsRpcResult,
@@ -247,9 +242,6 @@ class PaymentsClient {
// The URL loader factory for the request.
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
- // The pref service for this client.
- PrefService* const pref_service_;
-
// Provided in constructor; not owned by PaymentsClient.
identity::IdentityManager* const identity_manager_;
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 6f9edcede0d..620f21c128e 100644
--- a/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -17,14 +17,13 @@
#include "base/values.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
-#include "components/autofill/core/browser/credit_card_save_manager.h"
-#include "components/autofill/core/browser/local_card_migration_manager.h"
+#include "components/autofill/core/browser/payments/credit_card_save_manager.h"
+#include "components/autofill/core/browser/payments/local_card_migration_manager.h"
#include "components/autofill/core/browser/payments/payments_client.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#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"
@@ -77,10 +76,9 @@ class PaymentsClientTest : public testing::Test {
test_shared_loader_factory_ =
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_);
- TestingPrefServiceSimple pref_service_;
client_ = std::make_unique<PaymentsClient>(
- test_shared_loader_factory_, &pref_service_,
- identity_test_env_.identity_manager(), &test_personal_data_);
+ test_shared_loader_factory_, identity_test_env_.identity_manager(),
+ &test_personal_data_);
test_personal_data_.SetAccountInfoForPayments(
identity_test_env_.MakePrimaryAccountAvailable("example@gmail.com"));
}
@@ -513,29 +511,6 @@ TEST_F(PaymentsClientTest, GetDetailsIncludesUnknownUploadCardSourceInRequest) {
std::string::npos);
}
-TEST_F(PaymentsClientTest, GetUploadAccountFromSyncTest) {
- EnableAutofillGetPaymentsIdentityFromSync();
- // Set up a different account.
- const AccountInfo& secondary_account_info =
- identity_test_env_.MakeAccountAvailable("secondary@gmail.com");
- test_personal_data_.SetAccountInfoForPayments(secondary_account_info);
-
- StartUploading(/*include_cvc=*/true);
- ReturnResponse(net::HTTP_OK, "{}");
-
- // Issue a token for the secondary account.
- identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
- secondary_account_info.account_id, "secondary_account_token",
- base::Time::Now() + base::TimeDelta::FromDays(10));
-
- // Verify the auth header.
- std::string auth_header_value;
- EXPECT_TRUE(intercepted_headers_.GetHeader(
- net::HttpRequestHeaders::kAuthorization, &auth_header_value))
- << intercepted_headers_.ToString();
- EXPECT_EQ("Bearer secondary_account_token", auth_header_value);
-}
-
TEST_F(PaymentsClientTest, GetUploadDetailsVariationsTest) {
// Register a trial and variation id, so that there is data in variations
// headers. Also, the variations header provider may have been registered to
@@ -567,6 +542,103 @@ TEST_F(PaymentsClientTest, GetUploadDetailsVariationsTestExperimentFlagOff) {
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
+TEST_F(PaymentsClientTest, GetDetailsIncludeBillableServiceNumber) {
+ StartGettingUploadDetails();
+
+ // Verify that billable service number was included in the request.
+ EXPECT_TRUE(GetUploadData().find("\"billable_service\":12345") !=
+ std::string::npos);
+}
+
+TEST_F(PaymentsClientTest, GetDetailsFollowedByUploadSuccess) {
+ StartGettingUploadDetails();
+ ReturnResponse(
+ net::HTTP_OK,
+ "{ \"context_token\": \"some_token\", \"legal_message\": {} }");
+ EXPECT_EQ(AutofillClient::SUCCESS, result_);
+
+ result_ = AutofillClient::NONE;
+
+ StartUploading(/*include_cvc=*/true);
+ IssueOAuthToken();
+ ReturnResponse(net::HTTP_OK, "{}");
+ EXPECT_EQ(AutofillClient::SUCCESS, result_);
+}
+
+TEST_F(PaymentsClientTest, GetDetailsFollowedByMigrationSuccess) {
+ StartGettingUploadDetails();
+ ReturnResponse(
+ net::HTTP_OK,
+ "{ \"context_token\": \"some_token\", \"legal_message\": {} }");
+ EXPECT_EQ(AutofillClient::SUCCESS, result_);
+
+ result_ = AutofillClient::NONE;
+
+ StartMigrating(/*has_cardholder_name=*/true);
+ IssueOAuthToken();
+ ReturnResponse(
+ net::HTTP_OK,
+ "{\"save_result\":[],\"value_prop_display_text\":\"display text\"}");
+ EXPECT_EQ(AutofillClient::SUCCESS, result_);
+}
+
+TEST_F(PaymentsClientTest, GetDetailsMissingContextToken) {
+ StartGettingUploadDetails();
+ ReturnResponse(net::HTTP_OK, "{ \"legal_message\": {} }");
+ EXPECT_EQ(AutofillClient::PERMANENT_FAILURE, result_);
+}
+
+TEST_F(PaymentsClientTest, GetDetailsMissingLegalMessage) {
+ StartGettingUploadDetails();
+ ReturnResponse(net::HTTP_OK, "{ \"context_token\": \"some_token\" }");
+ EXPECT_EQ(AutofillClient::PERMANENT_FAILURE, result_);
+ EXPECT_EQ(nullptr, legal_message_.get());
+}
+
+TEST_F(PaymentsClientTest, SupportedCardBinRangesParsesCorrectly) {
+ StartGettingUploadDetails();
+ ReturnResponse(
+ net::HTTP_OK,
+ "{"
+ " \"context_token\" : \"some_token\","
+ " \"legal_message\" : {},"
+ " \"supported_card_bin_ranges_string\" : \"1234,300000-555555,765\""
+ "}");
+ EXPECT_EQ(AutofillClient::SUCCESS, result_);
+ // Check that |supported_card_bin_ranges_| has the two entries specified in
+ // ReturnResponse(~) above.
+ ASSERT_EQ(3U, supported_card_bin_ranges_.size());
+ EXPECT_EQ(1234, supported_card_bin_ranges_[0].first);
+ EXPECT_EQ(1234, supported_card_bin_ranges_[0].second);
+ EXPECT_EQ(300000, supported_card_bin_ranges_[1].first);
+ EXPECT_EQ(555555, supported_card_bin_ranges_[1].second);
+ EXPECT_EQ(765, supported_card_bin_ranges_[2].first);
+ EXPECT_EQ(765, supported_card_bin_ranges_[2].second);
+}
+
+TEST_F(PaymentsClientTest, GetUploadAccountFromSyncTest) {
+ EnableAutofillGetPaymentsIdentityFromSync();
+ // Set up a different account.
+ const AccountInfo& secondary_account_info =
+ identity_test_env_.MakeAccountAvailable("secondary@gmail.com");
+ test_personal_data_.SetAccountInfoForPayments(secondary_account_info);
+
+ StartUploading(/*include_cvc=*/true);
+ ReturnResponse(net::HTTP_OK, "{}");
+
+ // Issue a token for the secondary account.
+ identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+ secondary_account_info.account_id, "secondary_account_token",
+ base::Time::Now() + base::TimeDelta::FromDays(10));
+
+ // Verify the auth header.
+ std::string auth_header_value;
+ EXPECT_TRUE(intercepted_headers_.GetHeader(
+ net::HttpRequestHeaders::kAuthorization, &auth_header_value))
+ << intercepted_headers_.ToString();
+ EXPECT_EQ("Bearer secondary_account_token", auth_header_value);
+}
+
TEST_F(PaymentsClientTest, UploadCardVariationsTest) {
// Register a trial and variation id, so that there is data in variations
// headers. Also, the variations header provider may have been registered to
@@ -664,14 +736,6 @@ TEST_F(PaymentsClientTest, MigrateCardsVariationsTestExperimentFlagOff) {
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
-TEST_F(PaymentsClientTest, GetDetailsIncludeBillableServiceNumber) {
- StartGettingUploadDetails();
-
- // Verify that billable service number was included in the request.
- EXPECT_TRUE(GetUploadData().find("\"billable_service\":12345") !=
- std::string::npos);
-}
-
TEST_F(PaymentsClientTest, UploadSuccessWithoutServerId) {
StartUploading(/*include_cvc=*/true);
IssueOAuthToken();
@@ -914,57 +978,12 @@ TEST_F(PaymentsClientTest, MigrationSuccessWithDisplayText) {
EXPECT_EQ("display text", display_text_);
}
-TEST_F(PaymentsClientTest, GetDetailsFollowedByUploadSuccess) {
- StartGettingUploadDetails();
- ReturnResponse(
- net::HTTP_OK,
- "{ \"context_token\": \"some_token\", \"legal_message\": {} }");
- EXPECT_EQ(AutofillClient::SUCCESS, result_);
-
- result_ = AutofillClient::NONE;
-
- StartUploading(/*include_cvc=*/true);
- IssueOAuthToken();
- ReturnResponse(net::HTTP_OK, "{}");
- EXPECT_EQ(AutofillClient::SUCCESS, result_);
-}
-
-TEST_F(PaymentsClientTest, GetDetailsFollowedByMigrationSuccess) {
- StartGettingUploadDetails();
- ReturnResponse(
- net::HTTP_OK,
- "{ \"context_token\": \"some_token\", \"legal_message\": {} }");
- EXPECT_EQ(AutofillClient::SUCCESS, result_);
-
- result_ = AutofillClient::NONE;
-
- StartMigrating(/*has_cardholder_name=*/true);
- IssueOAuthToken();
- ReturnResponse(
- net::HTTP_OK,
- "{\"save_result\":[],\"value_prop_display_text\":\"display text\"}");
- EXPECT_EQ(AutofillClient::SUCCESS, result_);
-}
-
TEST_F(PaymentsClientTest, UnmaskMissingPan) {
StartUnmasking();
ReturnResponse(net::HTTP_OK, "{}");
EXPECT_EQ(AutofillClient::PERMANENT_FAILURE, result_);
}
-TEST_F(PaymentsClientTest, GetDetailsMissingContextToken) {
- StartGettingUploadDetails();
- ReturnResponse(net::HTTP_OK, "{ \"legal_message\": {} }");
- EXPECT_EQ(AutofillClient::PERMANENT_FAILURE, result_);
-}
-
-TEST_F(PaymentsClientTest, GetDetailsMissingLegalMessage) {
- StartGettingUploadDetails();
- ReturnResponse(net::HTTP_OK, "{ \"context_token\": \"some_token\" }");
- EXPECT_EQ(AutofillClient::PERMANENT_FAILURE, result_);
- EXPECT_EQ(nullptr, legal_message_.get());
-}
-
TEST_F(PaymentsClientTest, RetryFailure) {
StartUnmasking();
IssueOAuthToken();
diff --git a/chromium/components/autofill/core/browser/payments/payments_request.h b/chromium/components/autofill/core/browser/payments/payments_request.h
index e71d554d7de..61916ad82cc 100644
--- a/chromium/components/autofill/core/browser/payments/payments_request.h
+++ b/chromium/components/autofill/core/browser/payments/payments_request.h
@@ -28,7 +28,7 @@ class PaymentsRequest {
virtual std::string GetRequestContent() = 0;
// Parses the required elements of the HTTP response.
- virtual void ParseResponse(base::Value response) = 0;
+ virtual void ParseResponse(const base::Value& response) = 0;
// Returns true if all of the required elements were successfully retrieved by
// a call to ParseResponse.
diff --git a/chromium/components/autofill/core/browser/payments/payments_service_url.cc b/chromium/components/autofill/core/browser/payments/payments_service_url.cc
index f545e9a16d7..442f7fa25ca 100644
--- a/chromium/components/autofill/core/browser/payments/payments_service_url.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_service_url.cc
@@ -21,11 +21,22 @@
namespace autofill {
namespace {
+// Service URLs used for calls to Google Payments endpoints.
const char kProdPaymentsServiceUrl[] = "https://payments.google.com/";
-
const char kSandboxPaymentsSecureServiceUrl[] =
"https://payments.sandbox.google.com/";
+// URLs used when opening the Payment methods management page from
+// chrome://settings/payments.
+const char kProdPaymentsManageCardsUrl[] =
+ "https://pay.google.com/payments/"
+ "home?utm_source=chrome&utm_medium=settings&utm_campaign=payment-methods#"
+ "paymentMethods";
+const char kSandboxPaymentsManageCardsUrl[] =
+ "https://pay.sandbox.google.com/payments/"
+ "home?utm_source=chrome&utm_medium=settings&utm_campaign=payment-methods#"
+ "paymentMethods";
+
} // namespace
namespace payments {
@@ -44,15 +55,14 @@ GURL GetBaseSecureUrl() {
: kSandboxPaymentsSecureServiceUrl);
}
-GURL GetManageInstrumentsUrl(size_t user_index) {
- std::string path =
- base::StringPrintf("u/%" PRIuS "#paymentMethods", user_index);
- return GetBaseSecureUrl().Resolve(path);
+GURL GetManageInstrumentsUrl() {
+ return GURL(IsPaymentsProductionEnabled() ? kProdPaymentsManageCardsUrl
+ : kSandboxPaymentsManageCardsUrl);
}
-GURL GetManageAddressesUrl(size_t user_index) {
+GURL GetManageAddressesUrl() {
// Billing addresses are now managed as a part of the payment instrument.
- return GetManageInstrumentsUrl(user_index);
+ return GetManageInstrumentsUrl();
}
} // namespace payments
diff --git a/chromium/components/autofill/core/browser/payments/payments_service_url.h b/chromium/components/autofill/core/browser/payments/payments_service_url.h
index b28aa36fd83..a4c5d232482 100644
--- a/chromium/components/autofill/core/browser/payments/payments_service_url.h
+++ b/chromium/components/autofill/core/browser/payments/payments_service_url.h
@@ -16,16 +16,13 @@ namespace payments {
// should be used.
bool IsPaymentsProductionEnabled();
-// Returns the base URL to use for all Google Payments activity (RPCs and/or
-// navigation).
+// Returns the base URL to use for calls to Google Payments endpoints.
GURL GetBaseSecureUrl();
// Returns the URL to navigate to in order to allow the user to edit or delete
-// payment instruments (credit cards) or addresses, respectively. |user_index|
-// is the index into the list of signed-in GAIA profiles for which this request
-// is being made.
-GURL GetManageInstrumentsUrl(size_t user_index);
-GURL GetManageAddressesUrl(size_t user_index);
+// payment instruments (credit cards) or addresses, respectively.
+GURL GetManageInstrumentsUrl();
+GURL GetManageAddressesUrl();
} // namespace payments
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/payments/payments_service_url_unittest.cc b/chromium/components/autofill/core/browser/payments/payments_service_url_unittest.cc
index 8cdc5001257..49182d3f94d 100644
--- a/chromium/components/autofill/core/browser/payments/payments_service_url_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_service_url_unittest.cc
@@ -16,20 +16,25 @@ TEST(PaymentsServiceSandboxUrl, CheckSandboxUrls) {
switches::kWalletServiceUseSandbox, "1");
const char kExpectedSandboxURL[] =
- "https://payments.sandbox.google.com/u/1#paymentMethods";
+ "https://pay.sandbox.google.com/payments/"
+ "home?utm_source=chrome&utm_medium=settings&utm_campaign=payment-methods#"
+ "paymentMethods";
- EXPECT_EQ(kExpectedSandboxURL, GetManageInstrumentsUrl(1).spec());
- EXPECT_EQ(kExpectedSandboxURL, GetManageAddressesUrl(1).spec());
+ EXPECT_EQ(kExpectedSandboxURL, GetManageInstrumentsUrl().spec());
+ EXPECT_EQ(kExpectedSandboxURL, GetManageAddressesUrl().spec());
}
TEST(PaymentsServiceSandboxUrl, CheckProdUrls) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kWalletServiceUseSandbox, "0");
- const char kExpectedURL[] = "https://payments.google.com/u/1#paymentMethods";
+ const char kExpectedURL[] =
+ "https://pay.google.com/payments/"
+ "home?utm_source=chrome&utm_medium=settings&utm_campaign=payment-methods#"
+ "paymentMethods";
- EXPECT_EQ(kExpectedURL, GetManageInstrumentsUrl(1).spec());
- EXPECT_EQ(kExpectedURL, GetManageAddressesUrl(1).spec());
+ EXPECT_EQ(kExpectedURL, GetManageInstrumentsUrl().spec());
+ EXPECT_EQ(kExpectedURL, GetManageAddressesUrl().spec());
}
} // namespace payments
diff --git a/chromium/components/autofill/core/browser/payments/payments_util.cc b/chromium/components/autofill/core/browser/payments/payments_util.cc
index 51beb608048..b5775344bbb 100644
--- a/chromium/components/autofill/core/browser/payments/payments_util.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_util.cc
@@ -4,58 +4,53 @@
#include "components/autofill/core/browser/payments/payments_util.h"
-#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/personal_data_manager.h"
-#include "components/autofill/core/common/autofill_features.h"
-#include "components/autofill/core/common/autofill_prefs.h"
-#include "components/prefs/pref_service.h"
namespace autofill {
namespace payments {
+namespace {
+constexpr int kCustomerHasNoBillingCustomerNumber = 0;
+}
+
int64_t GetBillingCustomerId(PersonalDataManager* personal_data_manager,
- PrefService* pref_service,
bool should_log_validity) {
DCHECK(personal_data_manager);
- DCHECK(pref_service);
-
- if (base::FeatureList::IsEnabled(
- features::kAutofillUsePaymentsCustomerData) ||
- base::FeatureList::IsEnabled(
- features::kAutofillEnableAccountWalletStorage)) {
- // Get billing customer ID from the synced PaymentsCustomerData.
- PaymentsCustomerData* customer_data =
- personal_data_manager->GetPaymentsCustomerData();
- if (customer_data && !customer_data->customer_id.empty()) {
- int64_t billing_customer_id = 0;
- if (base::StringToInt64(base::StringPiece(customer_data->customer_id),
- &billing_customer_id)) {
- if (should_log_validity) {
- AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus(
- AutofillMetrics::BillingIdStatus::VALID);
- }
- return billing_customer_id;
- } else {
- if (should_log_validity) {
- AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus(
- AutofillMetrics::BillingIdStatus::PARSE_ERROR);
- }
+
+ // Get billing customer ID from the synced PaymentsCustomerData.
+ PaymentsCustomerData* customer_data =
+ personal_data_manager->GetPaymentsCustomerData();
+ if (customer_data && !customer_data->customer_id.empty()) {
+ int64_t billing_customer_id = 0;
+ if (base::StringToInt64(base::StringPiece(customer_data->customer_id),
+ &billing_customer_id)) {
+ if (should_log_validity) {
+ AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus(
+ AutofillMetrics::BillingIdStatus::VALID);
}
+ return billing_customer_id;
} else {
if (should_log_validity) {
AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus(
- AutofillMetrics::BillingIdStatus::MISSING);
+ AutofillMetrics::BillingIdStatus::PARSE_ERROR);
}
}
+ } else {
+ if (should_log_validity) {
+ AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus(
+ AutofillMetrics::BillingIdStatus::MISSING);
+ }
}
+ return kCustomerHasNoBillingCustomerNumber;
+}
- // Get billing customer ID from priority preferences.
- return static_cast<int64_t>(
- pref_service->GetDouble(prefs::kAutofillBillingCustomerNumber));
+bool HasGooglePaymentsAccount(PersonalDataManager* personal_data_manager) {
+ return GetBillingCustomerId(personal_data_manager) !=
+ kCustomerHasNoBillingCustomerNumber;
}
} // namespace payments
diff --git a/chromium/components/autofill/core/browser/payments/payments_util.h b/chromium/components/autofill/core/browser/payments/payments_util.h
index aeca52bf3b4..31ca1053e15 100644
--- a/chromium/components/autofill/core/browser/payments/payments_util.h
+++ b/chromium/components/autofill/core/browser/payments/payments_util.h
@@ -7,8 +7,6 @@
#include <stdint.h>
-class PrefService;
-
namespace autofill {
class PersonalDataManager;
@@ -20,9 +18,11 @@ namespace payments {
// if the customer ID was not found. If |should_log_validity| is true, will
// report on the validity state of the customer ID in PaymentsCustomerData.
int64_t GetBillingCustomerId(PersonalDataManager* personal_data_manager,
- PrefService* pref_service,
bool should_log_validity = false);
+// Returns if the customer has an existing Google payments account.
+bool HasGooglePaymentsAccount(PersonalDataManager* personal_data_manager);
+
} // namespace payments
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/payments/payments_util_unittest.cc b/chromium/components/autofill/core/browser/payments/payments_util_unittest.cc
index 9ce775cea00..d2fb85040a6 100644
--- a/chromium/components/autofill/core/browser/payments/payments_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/payments_util_unittest.cc
@@ -5,14 +5,9 @@
#include "components/autofill/core/browser/payments/payments_util.h"
#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
-#include "components/autofill/core/common/autofill_features.h"
-#include "components/autofill/core/common/autofill_prefs.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
@@ -24,30 +19,20 @@ class PaymentsUtilTest : public testing::Test {
~PaymentsUtilTest() override {}
protected:
- void SetUp() override {
- pref_service_.registry()->RegisterDoublePref(
- prefs::kAutofillBillingCustomerNumber, 0.0);
- }
-
- base::test::ScopedFeatureList scoped_feature_list_;
TestPersonalDataManager personal_data_manager_;
- TestingPrefServiceSimple pref_service_;
private:
DISALLOW_COPY_AND_ASSIGN(PaymentsUtilTest);
};
TEST_F(PaymentsUtilTest, GetBillingCustomerId_PaymentsCustomerData_Normal) {
- scoped_feature_list_.InitAndEnableFeature(
- features::kAutofillUsePaymentsCustomerData);
base::HistogramTester histogram_tester;
personal_data_manager_.SetPaymentsCustomerData(
std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
- EXPECT_EQ(123456,
- GetBillingCustomerId(&personal_data_manager_, &pref_service_,
- /*should_log_validity=*/true));
+ EXPECT_EQ(123456, GetBillingCustomerId(&personal_data_manager_,
+ /*should_log_validity=*/true));
histogram_tester.ExpectUniqueSample(
"Autofill.PaymentsCustomerDataBillingIdStatus",
@@ -55,14 +40,12 @@ TEST_F(PaymentsUtilTest, GetBillingCustomerId_PaymentsCustomerData_Normal) {
}
TEST_F(PaymentsUtilTest, GetBillingCustomerId_PaymentsCustomerData_Garbage) {
- scoped_feature_list_.InitAndEnableFeature(
- features::kAutofillUsePaymentsCustomerData);
base::HistogramTester histogram_tester;
personal_data_manager_.SetPaymentsCustomerData(
std::make_unique<PaymentsCustomerData>(/*customer_id=*/"garbage"));
- EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_,
+ EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_,
/*should_log_validity=*/true));
histogram_tester.ExpectUniqueSample(
@@ -71,57 +54,27 @@ TEST_F(PaymentsUtilTest, GetBillingCustomerId_PaymentsCustomerData_Garbage) {
}
TEST_F(PaymentsUtilTest, GetBillingCustomerId_PaymentsCustomerData_NoData) {
- scoped_feature_list_.InitAndEnableFeature(
- features::kAutofillUsePaymentsCustomerData);
base::HistogramTester histogram_tester;
// Explictly do not set PaymentsCustomerData. Nothing crashes and the returned
// customer ID is 0.
- EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_,
+ EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_,
/*should_log_validity=*/true));
histogram_tester.ExpectUniqueSample(
"Autofill.PaymentsCustomerDataBillingIdStatus",
AutofillMetrics::BillingIdStatus::MISSING, 1);
}
-TEST_F(PaymentsUtilTest,
- GetBillingCustomerId_PaymentsCustomerData_NoDataFallback) {
- scoped_feature_list_.InitAndEnableFeature(
- features::kAutofillUsePaymentsCustomerData);
- base::HistogramTester histogram_tester;
-
- // Explictly do not set PaymentsCustomerData but set a fallback to prefs.
- pref_service_.SetDouble(prefs::kAutofillBillingCustomerNumber, 123456.0);
-
- // We got the data from prefs and log that the PaymentsCustomerData is
- // invalid.
- EXPECT_EQ(123456,
- GetBillingCustomerId(&personal_data_manager_, &pref_service_,
- /*should_log_validity=*/true));
- histogram_tester.ExpectUniqueSample(
- "Autofill.PaymentsCustomerDataBillingIdStatus",
- AutofillMetrics::BillingIdStatus::MISSING, 1);
-}
-
-TEST_F(PaymentsUtilTest, GetBillingCustomerId_PriorityPrefs_Normal) {
- scoped_feature_list_.InitAndDisableFeature(
- features::kAutofillUsePaymentsCustomerData);
-
- pref_service_.SetDouble(prefs::kAutofillBillingCustomerNumber, 123456.0);
+TEST_F(PaymentsUtilTest, HasGooglePaymentsAccount_Normal) {
+ personal_data_manager_.SetPaymentsCustomerData(
+ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
- EXPECT_EQ(123456,
- GetBillingCustomerId(&personal_data_manager_, &pref_service_,
- /*should_log_validity=*/true));
+ EXPECT_TRUE(HasGooglePaymentsAccount(&personal_data_manager_));
}
-TEST_F(PaymentsUtilTest, GetBillingCustomerId_PriorityPrefs_NoData) {
- scoped_feature_list_.InitAndDisableFeature(
- features::kAutofillUsePaymentsCustomerData);
-
- // Explictly do not set Prefs data. Nothing crashes and the returned customer
- // ID is 0.
- EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_,
- /*should_log_validity=*/true));
+TEST_F(PaymentsUtilTest, HasGooglePaymentsAccount_NoData) {
+ // Explicitly do not set Prefs data. Nothing crashes and returns false.
+ EXPECT_FALSE(HasGooglePaymentsAccount(&personal_data_manager_));
}
} // namespace payments
diff --git a/chromium/components/autofill/core/browser/risk_data_loader.h b/chromium/components/autofill/core/browser/payments/risk_data_loader.h
index 2b8468bb584..a9860ee588c 100644
--- a/chromium/components/autofill/core/browser/risk_data_loader.h
+++ b/chromium/components/autofill/core/browser/payments/risk_data_loader.h
@@ -2,8 +2,8 @@
// 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_RISK_DATA_LOADER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_RISK_DATA_LOADER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_RISK_DATA_LOADER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_RISK_DATA_LOADER_H_
#include <string>
@@ -23,4 +23,4 @@ class RiskDataLoader {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_RISK_DATA_LOADER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_RISK_DATA_LOADER_H_
diff --git a/chromium/components/autofill/core/browser/strike_database.cc b/chromium/components/autofill/core/browser/payments/strike_database.cc
index 41002501b2b..10ff55f4dc7 100644
--- a/chromium/components/autofill/core/browser/strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/strike_database.cc
@@ -2,7 +2,7 @@
// 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.h"
+#include "components/autofill/core/browser/payments/strike_database.h"
#include <algorithm>
#include <string>
diff --git a/chromium/components/autofill/core/browser/strike_database.h b/chromium/components/autofill/core/browser/payments/strike_database.h
index 8b8915df770..029aebe6e3f 100644
--- a/chromium/components/autofill/core/browser/strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/strike_database.h
@@ -2,8 +2,8 @@
// 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_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_STRIKE_DATABASE_H_
#include <map>
#include <memory>
@@ -165,4 +165,4 @@ class StrikeDatabase : public KeyedService {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_base.cc b/chromium/components/autofill/core/browser/payments/strike_database_integrator_base.cc
index 5b0426188a7..1d0f11324dd 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_base.cc
+++ b/chromium/components/autofill/core/browser/payments/strike_database_integrator_base.cc
@@ -2,7 +2,7 @@
// 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_base.h"
+#include "components/autofill/core/browser/payments/strike_database_integrator_base.h"
#include <algorithm>
#include <string>
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_base.h b/chromium/components/autofill/core/browser/payments/strike_database_integrator_base.h
index 3e1bf565d8a..63e624e56f0 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_base.h
+++ b/chromium/components/autofill/core/browser/payments/strike_database_integrator_base.h
@@ -2,10 +2,10 @@
// 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_BASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_BASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_STRIKE_DATABASE_INTEGRATOR_BASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_STRIKE_DATABASE_INTEGRATOR_BASE_H_
-#include "components/autofill/core/browser/strike_database.h"
+#include "components/autofill/core/browser/payments/strike_database.h"
namespace autofill {
@@ -104,4 +104,4 @@ class StrikeDatabaseIntegratorBase {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_BASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_STRIKE_DATABASE_INTEGRATOR_BASE_H_
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc b/chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database.cc
index c5be5139c42..99e701a1233 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database.cc
@@ -2,7 +2,7 @@
// 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/payments/strike_database_integrator_test_strike_database.h"
#include "components/autofill/core/browser/proto/strike_data.pb.h"
diff --git a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h b/chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database.h
index 3a50f6e75f5..22afb7a7883 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database.h
@@ -2,13 +2,13 @@
// 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_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_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"
+#include "components/autofill/core/browser/payments/strike_database.h"
+#include "components/autofill/core/browser/payments/strike_database_integrator_base.h"
namespace autofill {
@@ -33,4 +33,4 @@ class StrikeDatabaseIntegratorTestStrikeDatabase
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASE_INTEGRATOR_TEST_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_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/payments/strike_database_integrator_test_strike_database_unittest.cc
index a6e961b7fde..971af060325 100644
--- a/chromium/components/autofill/core/browser/strike_database_integrator_test_strike_database_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/strike_database_integrator_test_strike_database_unittest.cc
@@ -2,7 +2,7 @@
// 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/payments/strike_database_integrator_test_strike_database.h"
#include <utility>
#include <vector>
@@ -22,11 +22,13 @@ namespace autofill {
class StrikeDatabaseIntegratorTestStrikeDatabaseTest : public ::testing::Test {
public:
StrikeDatabaseIntegratorTestStrikeDatabaseTest()
- : strike_database_(new StrikeDatabase(InitFilePath())) {}
+ : strike_database_service_(InitFilePath()),
+ strike_database_(&strike_database_service_) {}
protected:
base::HistogramTester* GetHistogramTester() { return &histogram_tester_; }
base::test::ScopedTaskEnvironment scoped_task_environment_;
+ StrikeDatabase strike_database_service_;
StrikeDatabaseIntegratorTestStrikeDatabase strike_database_;
private:
diff --git a/chromium/components/autofill/core/browser/strike_database_unittest.cc b/chromium/components/autofill/core/browser/payments/strike_database_unittest.cc
index 88a5edeed45..508a1bc7652 100644
--- a/chromium/components/autofill/core/browser/strike_database_unittest.cc
+++ b/chromium/components/autofill/core/browser/payments/strike_database_unittest.cc
@@ -2,7 +2,7 @@
// 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.h"
+#include "components/autofill/core/browser/payments/strike_database.h"
#include <utility>
#include <vector>
diff --git a/chromium/components/autofill/core/browser/test_credit_card_save_manager.cc b/chromium/components/autofill/core/browser/payments/test_credit_card_save_manager.cc
index 21007fe0eb0..19fc90cace1 100644
--- a/chromium/components/autofill/core/browser/test_credit_card_save_manager.cc
+++ b/chromium/components/autofill/core/browser/payments/test_credit_card_save_manager.cc
@@ -2,7 +2,7 @@
// 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_credit_card_save_manager.h"
+#include "components/autofill/core/browser/payments/test_credit_card_save_manager.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
diff --git a/chromium/components/autofill/core/browser/test_credit_card_save_manager.h b/chromium/components/autofill/core/browser/payments/test_credit_card_save_manager.h
index c01c302f7b8..7a16e63e196 100644
--- a/chromium/components/autofill/core/browser/test_credit_card_save_manager.h
+++ b/chromium/components/autofill/core/browser/payments/test_credit_card_save_manager.h
@@ -2,12 +2,12 @@
// 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_CREDIT_CARD_SAVE_MANAGER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_CREDIT_CARD_SAVE_MANAGER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_CREDIT_CARD_SAVE_MANAGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_CREDIT_CARD_SAVE_MANAGER_H_
#include <string>
-#include "components/autofill/core/browser/credit_card_save_manager.h"
+#include "components/autofill/core/browser/payments/credit_card_save_manager.h"
namespace autofill {
@@ -56,4 +56,4 @@ class TestCreditCardSaveManager : public CreditCardSaveManager {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_CREDIT_CARD_SAVE_MANAGER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_CREDIT_CARD_SAVE_MANAGER_H_
diff --git a/chromium/components/autofill/core/browser/test_credit_card_save_strike_database.cc b/chromium/components/autofill/core/browser/payments/test_credit_card_save_strike_database.cc
index ebeb05ae93c..14d8505572b 100644
--- a/chromium/components/autofill/core/browser/test_credit_card_save_strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/test_credit_card_save_strike_database.cc
@@ -2,7 +2,7 @@
// 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_credit_card_save_strike_database.h"
+#include "components/autofill/core/browser/payments/test_credit_card_save_strike_database.h"
namespace autofill {
diff --git a/chromium/components/autofill/core/browser/test_credit_card_save_strike_database.h b/chromium/components/autofill/core/browser/payments/test_credit_card_save_strike_database.h
index 070337c3510..0db857c5753 100644
--- a/chromium/components/autofill/core/browser/test_credit_card_save_strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/test_credit_card_save_strike_database.h
@@ -2,10 +2,10 @@
// 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_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
-#include "components/autofill/core/browser/credit_card_save_strike_database.h"
+#include "components/autofill/core/browser/payments/credit_card_save_strike_database.h"
namespace autofill {
@@ -16,4 +16,4 @@ class TestCreditCardSaveStrikeDatabase : public CreditCardSaveStrikeDatabase {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_CREDIT_CARD_SAVE_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/test_legacy_strike_database.cc b/chromium/components/autofill/core/browser/payments/test_legacy_strike_database.cc
index 28d334b3475..0ec6a57d837 100644
--- a/chromium/components/autofill/core/browser/test_legacy_strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/test_legacy_strike_database.cc
@@ -2,7 +2,7 @@
// 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_legacy_strike_database.h"
+#include "components/autofill/core/browser/payments/test_legacy_strike_database.h"
#include "components/autofill/core/browser/proto/strike_data.pb.h"
diff --git a/chromium/components/autofill/core/browser/test_legacy_strike_database.h b/chromium/components/autofill/core/browser/payments/test_legacy_strike_database.h
index ddf878fcf34..ca8ca1a7498 100644
--- a/chromium/components/autofill/core/browser/test_legacy_strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/test_legacy_strike_database.h
@@ -2,8 +2,8 @@
// 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_LEGACY_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LEGACY_STRIKE_DATABASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_LEGACY_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_LEGACY_STRIKE_DATABASE_H_
#include <memory>
#include <string>
@@ -11,7 +11,7 @@
#include <utility>
#include <vector>
-#include "components/autofill/core/browser/legacy_strike_database.h"
+#include "components/autofill/core/browser/payments/legacy_strike_database.h"
namespace autofill {
@@ -42,4 +42,4 @@ class TestLegacyStrikeDatabase : public LegacyStrikeDatabase {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LEGACY_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_LEGACY_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc b/chromium/components/autofill/core/browser/payments/test_local_card_migration_manager.cc
index b9808476079..0ccf4c7f93a 100644
--- a/chromium/components/autofill/core/browser/test_local_card_migration_manager.cc
+++ b/chromium/components/autofill/core/browser/payments/test_local_card_migration_manager.cc
@@ -2,12 +2,12 @@
// 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_manager.h"
+#include "components/autofill/core/browser/payments/test_local_card_migration_manager.h"
#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/payments/payments_util.h"
#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 "components/autofill/core/common/autofill_payments_features.h"
namespace autofill {
@@ -30,12 +30,11 @@ bool TestLocalCardMigrationManager::IsCreditCardMigrationEnabled() {
features::LocalCardMigrationExperimentalFlag::kMigrationDisabled;
bool has_google_payments_account =
- (static_cast<int64_t>(payments_client_->GetPrefService()->GetDouble(
- prefs::kAutofillBillingCustomerNumber)) != 0);
+ (payments::GetBillingCustomerId(personal_data_manager_) != 0);
bool sync_feature_enabled =
(personal_data_manager_->GetSyncSigninState() ==
- AutofillSyncSigninState::kSignedInAndSyncFeature);
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled);
return migration_experiment_enabled && has_google_payments_account &&
(sync_feature_enabled ||
diff --git a/chromium/components/autofill/core/browser/test_local_card_migration_manager.h b/chromium/components/autofill/core/browser/payments/test_local_card_migration_manager.h
index 722d366dd20..25d38d7aefb 100644
--- a/chromium/components/autofill/core/browser/test_local_card_migration_manager.h
+++ b/chromium/components/autofill/core/browser/payments/test_local_card_migration_manager.h
@@ -2,15 +2,15 @@
// 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_MANAGER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_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/payments/local_card_migration_manager.h"
#include "components/autofill/core/browser/sync_utils.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
@@ -79,4 +79,4 @@ class TestLocalCardMigrationManager : public LocalCardMigrationManager {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
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 e58fe67248f..ddcce624bf8 100644
--- a/chromium/components/autofill/core/browser/payments/test_payments_client.cc
+++ b/chromium/components/autofill/core/browser/payments/test_payments_client.cc
@@ -13,11 +13,9 @@ namespace payments {
TestPaymentsClient::TestPaymentsClient(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_,
- PrefService* pref_service,
identity::IdentityManager* identity_manager,
PersonalDataManager* personal_data_manager)
: PaymentsClient(url_loader_factory_,
- pref_service,
identity_manager,
personal_data_manager) {}
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 e7f6c928e48..779326cb54f 100644
--- a/chromium/components/autofill/core/browser/payments/test_payments_client.h
+++ b/chromium/components/autofill/core/browser/payments/test_payments_client.h
@@ -22,7 +22,6 @@ class TestPaymentsClient : public payments::PaymentsClient {
public:
TestPaymentsClient(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_,
- PrefService* pref_service,
identity::IdentityManager* identity_manager,
PersonalDataManager* personal_data_manager);
diff --git a/chromium/components/autofill/core/browser/test_strike_database.cc b/chromium/components/autofill/core/browser/payments/test_strike_database.cc
index 4aee9cb4746..7b96773e25b 100644
--- a/chromium/components/autofill/core/browser/test_strike_database.cc
+++ b/chromium/components/autofill/core/browser/payments/test_strike_database.cc
@@ -2,7 +2,7 @@
// 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_strike_database.h"
+#include "components/autofill/core/browser/payments/test_strike_database.h"
#include "components/autofill/core/browser/proto/strike_data.pb.h"
diff --git a/chromium/components/autofill/core/browser/test_strike_database.h b/chromium/components/autofill/core/browser/payments/test_strike_database.h
index d46be27bc4b..803a1f152e4 100644
--- a/chromium/components/autofill/core/browser/test_strike_database.h
+++ b/chromium/components/autofill/core/browser/payments/test_strike_database.h
@@ -2,8 +2,8 @@
// 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_STRIKE_DATABASE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_STRIKE_DATABASE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_STRIKE_DATABASE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_STRIKE_DATABASE_H_
#include <memory>
#include <string>
@@ -11,7 +11,7 @@
#include <utility>
#include <vector>
-#include "components/autofill/core/browser/strike_database.h"
+#include "components/autofill/core/browser/payments/strike_database.h"
namespace autofill {
@@ -41,4 +41,4 @@ class TestStrikeDatabase : public StrikeDatabase {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_STRIKE_DATABASE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_STRIKE_DATABASE_H_
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.cc b/chromium/components/autofill/core/browser/personal_data_manager.cc
index 902884a4b06..fc041e632ee 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager.cc
@@ -28,6 +28,7 @@
#include "components/autofill/core/browser/address_i18n.h"
#include "components/autofill/core/browser/autofill-inl.h"
#include "components/autofill/core/browser/autofill_country.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_download_manager.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_field.h"
@@ -36,6 +37,8 @@
#include "components/autofill/core/browser/country_data.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/label_formatter.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "components/autofill/core/browser/phone_number.h"
#include "components/autofill/core/browser/phone_number_i18n.h"
@@ -67,9 +70,6 @@ using ::i18n::addressinput::AddressField;
using ::i18n::addressinput::GetStreetAddressLinesAsSingleLine;
using ::i18n::addressinput::STREET_ADDRESS;
-// The length of a local profile GUID.
-const int LOCAL_GUID_LENGTH = 36;
-
template <typename T>
class FormGroupMatchesByGUIDFunctor {
public:
@@ -482,12 +482,21 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
}
is_data_loaded_ = true;
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
}
}
-void PersonalDataManager::AutofillMultipleChanged() {
- has_synced_new_data_ = true;
+void PersonalDataManager::AutofillMultipleChangedBySync() {
+ // After each change coming from sync we go through a two-step process:
+ // - First, we post a task on the DB sequence to (potentially) convert server
+ // addresses to local addresses and update cards accordingly.
+ // - This conversion task is concluded by a
+ // AutofillAddressConversionCompleted() notification. As a second step, we
+ // need to refresh the PDM's view of the data.
+ ConvertWalletAddressesAndUpdateWalletCards();
+}
+
+void PersonalDataManager::AutofillAddressConversionCompleted() {
Refresh();
}
@@ -571,7 +580,17 @@ AutofillSyncSigninState PersonalDataManager::GetSyncSigninState() const {
// Check if the user has turned on sync.
if (sync_service_->IsSyncFeatureEnabled()) {
- return AutofillSyncSigninState::kSignedInAndSyncFeature;
+ // TODO(crbug.com/906995): Remove this once the kStopSyncInPausedState
+ // feature is launched.
+ if (syncer::IsWebSignout(sync_service_->GetAuthError())) {
+ return AutofillSyncSigninState::kSyncPaused;
+ }
+ return AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled;
+ }
+
+ if (sync_service_->GetDisableReasons() ==
+ syncer::SyncService::DISABLE_REASON_PAUSED) {
+ return AutofillSyncSigninState::kSyncPaused;
}
// Check if the feature is enabled and if Wallet data types are supported.
@@ -1011,7 +1030,7 @@ void PersonalDataManager::UpdateClientValidityStates(
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();
+ ongoing_profile_changes_[profile->guid()].back().set_enforced();
client_profile_validator_->StartProfileValidation(
profile, base::BindOnce(&PersonalDataManager::OnValidated,
weak_factory_.GetWeakPtr()));
@@ -1138,16 +1157,13 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
// Get the profiles to suggest, which are already sorted.
std::vector<AutofillProfile*> sorted_profiles = GetProfilesToSuggest();
- // When suggesting with no prefix to match, consider suppressing disused
- // address suggestions as well as those based on invalid profile data.
+ // When suggesting with no prefix to match, suppress disused address
+ // suggestions as well as those based on invalid profile data.
if (field_contents_canon.empty()) {
- if (base::FeatureList::IsEnabled(
- features::kAutofillSuppressDisusedAddresses)) {
- const base::Time min_last_used =
- AutofillClock::Now() - kDisusedDataModelTimeDelta;
- suggestion_selection::RemoveProfilesNotUsedSinceTimestamp(
- min_last_used, &sorted_profiles);
- }
+ const base::Time min_last_used =
+ AutofillClock::Now() - kDisusedDataModelTimeDelta;
+ suggestion_selection::RemoveProfilesNotUsedSinceTimestamp(min_last_used,
+ &sorted_profiles);
}
std::vector<AutofillProfile*> matched_profiles;
@@ -1163,20 +1179,29 @@ std::vector<Suggestion> PersonalDataManager::GetProfileSuggestions(
matched_profiles, suggestions,
&unique_matched_profiles);
+ std::unique_ptr<LabelFormatter> formatter;
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ formatter = base::FeatureList::IsEnabled(
+ autofill::features::kAutofillUseImprovedLabelDisambiguation)
+ ? LabelFormatter::Create(app_locale_, type.GetStorableType(),
+ field_types, unique_matched_profiles)
+ : nullptr;
+#endif
+
// Generate disambiguating labels based on the list of matches.
std::vector<base::string16> 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];
- unique_suggestions[i].additional_label = labels[i];
+ if (formatter) {
+ labels = formatter->GetLabels(unique_matched_profiles);
+ } else {
+ AutofillProfile::CreateInferredLabels(unique_matched_profiles, &field_types,
+ type.GetStorableType(), 1,
+ app_locale_, &labels);
}
+ suggestion_selection::PrepareSuggestions(
+ formatter && data_util::ContainsAddress(formatter->groups()), labels,
+ &unique_suggestions);
return unique_suggestions;
}
@@ -1246,11 +1271,8 @@ std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions(
return std::vector<Suggestion>();
std::vector<CreditCard*> cards =
GetCreditCardsToSuggest(include_server_cards);
- // If enabled, suppress disused address profiles when triggered from an empty
- // field.
- if (field_contents.empty() &&
- base::FeatureList::IsEnabled(
- features::kAutofillSuppressDisusedCreditCards)) {
+ // Suppress disused address profiles when triggered from an empty field.
+ if (field_contents.empty()) {
const base::Time min_last_used =
AutofillClock::Now() - kDisusedDataModelTimeDelta;
RemoveExpiredCreditCardsNotUsedSinceTimestamp(AutofillClock::Now(),
@@ -1398,7 +1420,7 @@ void PersonalDataManager::OnValidated(const AutofillProfile* profile) {
if (!profile)
return;
- if (!ProfileChangesAreOnGoing(profile->guid()))
+ if (!ProfileChangesAreOngoing(profile->guid()))
return;
// Set the validity states updated, only when the validation has occurred. If
@@ -1589,26 +1611,46 @@ void PersonalDataManager::SetProfiles(std::vector<AutofillProfile>* profiles) {
ClearOnGoingProfileChanges();
+ // Means that a profile was added, removed or updated.
+ bool change_happened = false;
+
// Any profiles that are not in the new profile list should be removed from
// the web database
for (const auto& it : web_profiles_) {
- if (!FindByGUID<AutofillProfile>(*profiles, it->guid()))
+ if (!FindByGUID<AutofillProfile>(*profiles, it->guid())) {
RemoveProfileFromDB(it->guid());
+ change_happened = true;
+ }
}
// Update the web database with the new and existing profiles.
for (const AutofillProfile& it : *profiles) {
- if (FindByGUID<AutofillProfile>(web_profiles_, it.guid())) {
- UpdateProfileInDB(it);
- } else {
- AddProfileToDB(it);
+ const auto* existing_profile = GetProfileByGUID(it.guid());
+ // In SetProfiles, exceptionally, profiles are directly added/updated on the
+ // web_profiles_ before they are ready to be added or get updated in the
+ // database. Enforce the changes to make sure the database is also updated.
+ if (existing_profile) {
+ if (!existing_profile->EqualsForUpdatePurposes(it)) {
+ UpdateProfileInDB(it, /*enforced=*/true);
+ change_happened = true;
+ }
+ } else if (!FindByContents(web_profiles_, it)) {
+ AddProfileToDB(it, /*enforced=*/true);
+ change_happened = true;
}
}
- // Copy in the new profiles.
- web_profiles_.clear();
- for (const AutofillProfile& it : *profiles) {
- web_profiles_.push_back(std::make_unique<AutofillProfile>(it));
+ if (change_happened) {
+ // Copy in the new profiles.
+ web_profiles_.clear();
+ for (const AutofillProfile& it : *profiles) {
+ web_profiles_.push_back(std::make_unique<AutofillProfile>(it));
+ }
+ } else {
+ // When a change happens (add, update, remove), we would consequently call
+ // the NotifyPersonalDataChanged which notifies the tests to stop waiting.
+ // Otherwise, we need to stop them by calling the function directly.
+ NotifyPersonalDataObserver();
}
}
@@ -1744,23 +1786,6 @@ std::string PersonalDataManager::SaveImportedProfile(
return guid;
}
-void PersonalDataManager::NotifyPersonalDataChanged() {
- bool profile_changes_are_on_going = ProfileChangesAreOnGoing();
- for (PersonalDataManagerObserver& observer : observers_) {
- observer.OnPersonalDataChanged();
- if (!profile_changes_are_on_going) {
- observer.OnPersonalDataFinishedProfileTasks();
- }
- }
-
- // If new data was synced, try to convert new server profiles and update
- // server cards.
- if (has_synced_new_data_) {
- has_synced_new_data_ = false;
- ConvertWalletAddressesAndUpdateWalletCards();
- }
-}
-
std::string PersonalDataManager::OnAcceptedLocalCreditCardSave(
const CreditCard& imported_card) {
DCHECK(!imported_card.number().empty());
@@ -1871,7 +1896,7 @@ void PersonalDataManager::EnableWalletIntegrationPrefChanged() {
// Re-mask all server cards when the user turns off wallet card
// integration.
ResetFullServerCards();
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
}
}
@@ -1974,7 +1999,7 @@ void PersonalDataManager::OnAutofillProfileChanged(
const auto& profile = *(change.profile());
DCHECK(guid == profile.guid());
// Happens only in tests.
- if (!ProfileChangesAreOnGoing(guid)) {
+ if (!ProfileChangesAreOngoing(guid)) {
DVLOG(1) << "Received an unexpected response from database.";
return;
}
@@ -1991,7 +2016,7 @@ void PersonalDataManager::OnAutofillProfileChanged(
case AutofillProfileChange::UPDATE:
profiles_server_validities_need_update_ = true;
if (profile_exists &&
- (change.enforce_update() ||
+ (change.enforced() ||
!existing_profile->EqualsForUpdatePurposes(profile))) {
web_profiles_.erase(
FindElementByGUID<AutofillProfile>(web_profiles_, guid));
@@ -2025,6 +2050,16 @@ void PersonalDataManager::OnUserAcceptedUpstreamOffer() {
}
}
+void PersonalDataManager::NotifyPersonalDataObserver() {
+ bool profile_changes_are_ongoing = ProfileChangesAreOngoing();
+ for (PersonalDataManagerObserver& observer : observers_) {
+ observer.OnPersonalDataChanged();
+ if (!profile_changes_are_ongoing) {
+ observer.OnPersonalDataFinishedProfileTasks();
+ }
+ }
+}
+
std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
const AutofillType& type,
const base::string16& field_contents,
@@ -2303,171 +2338,23 @@ void PersonalDataManager::UpdateCardsBillingAddressReference(
}
void PersonalDataManager::ConvertWalletAddressesAndUpdateWalletCards() {
- // Copy the local profiles into a vector<AutofillProfile>. Theses are the
- // existing profiles. Get them sorted in decreasing order of frecency, so the
- // "best" profiles are checked first. Put the verified profiles last so the
- // server addresses have a chance to merge into the non-verified local
- // profiles.
- std::vector<AutofillProfile> local_profiles;
- for (AutofillProfile* existing_profile : GetProfiles()) {
- local_profiles.push_back(*existing_profile);
- }
-
- // Since we are already iterating on all the server profiles to convert Wallet
- // addresses and we will need to access them by guid later to update the
- // Wallet cards, create a map here.
- std::unordered_map<std::string, AutofillProfile*> server_id_profiles_map;
-
- // Create the map used to update credit card's billing addresses after the
- // conversion/merge.
- std::unordered_map<std::string, std::string> guids_merge_map;
-
- bool has_converted_addresses = ConvertWalletAddressesToLocalProfiles(
- &local_profiles, &server_id_profiles_map, &guids_merge_map);
- bool should_update_cards = UpdateWalletCardsAlreadyConvertedBillingAddresses(
- local_profiles, server_id_profiles_map, &guids_merge_map);
-
- if (has_converted_addresses) {
- // Save the local profiles to the DB.
- SetProfiles(&local_profiles);
- }
-
- if (should_update_cards || has_converted_addresses) {
- // Update the credit cards billing address relationship.
- UpdateCardsBillingAddressReference(guids_merge_map);
-
- // Force a reload of the profiles and cards.
- }
-}
-
-bool PersonalDataManager::ConvertWalletAddressesToLocalProfiles(
- std::vector<AutofillProfile>* local_profiles,
- std::unordered_map<std::string, AutofillProfile*>* server_id_profiles_map,
- std::unordered_map<std::string, std::string>* guids_merge_map) {
// If the full Sync feature isn't enabled, then do NOT convert any Wallet
// addresses to local ones.
if (!IsSyncFeatureEnabled()) {
- return false;
- }
-
- bool has_converted_addresses = false;
- for (std::unique_ptr<AutofillProfile>& wallet_address : server_profiles_) {
- // Add the profile to the map.
- server_id_profiles_map->emplace(wallet_address->server_id(),
- wallet_address.get());
-
- // If the address has not been converted yet, convert it.
- 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.
- std::string address_guid = MergeServerAddressesIntoProfiles(
- *wallet_address, local_profiles, app_locale_,
- GetAccountInfoForPaymentsServer().email);
-
- // Update the map to transfer the billing address relationship from the
- // server address to the converted/merged local profile.
- guids_merge_map->emplace(wallet_address->server_id(), address_guid);
-
- // Update the wallet addresses metadata to record the conversion.
- wallet_address->set_has_converted(true);
- database_helper_->GetServerDatabase()->UpdateServerAddressMetadata(
- *wallet_address);
-
- has_converted_addresses = true;
- }
- }
-
- return has_converted_addresses;
-}
-
-bool PersonalDataManager::UpdateWalletCardsAlreadyConvertedBillingAddresses(
- const std::vector<AutofillProfile>& local_profiles,
- const std::unordered_map<std::string, AutofillProfile*>&
- server_id_profiles_map,
- std::unordered_map<std::string, std::string>* guids_merge_map) const {
- // Look for server cards that still refer to server addresses but for which
- // there is no mapping. This can happen if it's a new card for which the
- // billing address has already been converted. This should be a no-op for most
- // situations. Otherwise, it should affect only one Wallet card, sinces users
- // do not add a lot of credit cards.
- AutofillProfileComparator comparator(app_locale_);
- bool should_update_cards = false;
- for (const std::unique_ptr<CreditCard>& wallet_card : server_credit_cards_) {
- std::string billing_address_id = wallet_card->billing_address_id();
-
- // If billing address refers to a server id and that id is not a key in the
- // |guids_merge_map|, it means that the card is new but the address was
- // already converted. Look for the matching converted profile.
- if (!billing_address_id.empty() &&
- billing_address_id.length() != LOCAL_GUID_LENGTH &&
- guids_merge_map->find(billing_address_id) == guids_merge_map->end()) {
- // Get the profile.
- auto it = server_id_profiles_map.find(billing_address_id);
- if (it != server_id_profiles_map.end()) {
- const AutofillProfile* billing_address = it->second;
-
- // Look for a matching local profile (DO NOT MERGE).
- for (const auto& local_profile : local_profiles) {
- if (comparator.AreMergeable(*billing_address, local_profile)) {
- // The Wallet address matches this local profile. Add this to the
- // merge mapping.
- guids_merge_map->emplace(billing_address_id, local_profile.guid());
- should_update_cards = true;
- break;
- }
- }
- }
- }
- }
-
- return should_update_cards;
-}
-
-// TODO(crbug.com/687975): Reuse MergeProfile in this function.
-// static
-std::string PersonalDataManager::MergeServerAddressesIntoProfiles(
- const AutofillProfile& server_address,
- std::vector<AutofillProfile>* existing_profiles,
- const std::string& app_locale,
- const std::string& primary_account_email) {
- // If there is already a local profile that is very similar, merge in any
- // missing values. Only merge with the first match.
- AutofillProfileComparator comparator(app_locale);
- for (auto& local_profile : *existing_profiles) {
- if (comparator.AreMergeable(server_address, local_profile) &&
- local_profile.SaveAdditionalInfo(server_address, app_locale)) {
- local_profile.set_modification_date(AutofillClock::Now());
- AutofillMetrics::LogWalletAddressConversionType(
- AutofillMetrics::CONVERTED_ADDRESS_MERGED);
- return local_profile.guid();
- }
+ // PDM expects that each call to
+ // ConvertWalletAddressesAndUpdateWalletCards() is followed by a
+ // AutofillAddressConversionCompleted() notification, simulate the
+ // notification here.
+ AutofillAddressConversionCompleted();
+ return;
}
- // If the server address was not merged with a local profile, add it to the
- // list.
- existing_profiles->push_back(server_address);
- // Set the profile as being local.
- existing_profiles->back().set_record_type(AutofillProfile::LOCAL_PROFILE);
- existing_profiles->back().set_modification_date(AutofillClock::Now());
-
- // Wallet addresses don't have an email address, use the one from the
- // currently signed-in account.
- base::string16 email = base::UTF8ToUTF16(primary_account_email);
- if (!email.empty())
- existing_profiles->back().SetRawInfo(EMAIL_ADDRESS, email);
-
- AutofillMetrics::LogWalletAddressConversionType(
- AutofillMetrics::CONVERTED_ADDRESS_ADDED);
-
- return server_address.guid();
+ database_helper_->GetServerDatabase()
+ ->ConvertWalletAddressesAndUpdateWalletCards(
+ app_locale_, GetAccountInfoForPaymentsServer().email);
}
bool PersonalDataManager::DeleteDisusedCreditCards() {
- if (!base::FeatureList::IsEnabled(
- features::kAutofillDeleteDisusedCreditCards)) {
- return false;
- }
-
// Only delete local cards, as server cards are managed by Payments.
auto cards = GetLocalCreditCards();
@@ -2499,12 +2386,6 @@ bool PersonalDataManager::DeleteDisusedCreditCards() {
}
bool PersonalDataManager::DeleteDisusedAddresses() {
- if (!base::FeatureList::IsEnabled(
- features::kAutofillDeleteDisusedAddresses)) {
- DVLOG(1) << "Deletion is disabled";
- return false;
- }
-
const std::vector<AutofillProfile*>& profiles = GetProfiles();
// Early exit when there are no profiles.
@@ -2584,21 +2465,25 @@ void PersonalDataManager::ResetProfileValidity() {
profiles_server_validities_need_update_ = true;
}
-void PersonalDataManager::AddProfileToDB(const AutofillProfile& profile) {
+void PersonalDataManager::AddProfileToDB(const AutofillProfile& profile,
+ bool enforced) {
if (profile.IsEmpty(app_locale_)) {
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
return;
}
- if (!ProfileChangesAreOnGoing(profile.guid())) {
- if (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()) ||
- FindByContents(web_profiles_, profile)) {
- NotifyPersonalDataChanged();
+ if (!ProfileChangesAreOngoing(profile.guid())) {
+ if (!enforced &&
+ (FindByGUID<AutofillProfile>(web_profiles_, profile.guid()) ||
+ FindByContents(web_profiles_, profile))) {
+ NotifyPersonalDataObserver();
return;
}
}
ongoing_profile_changes_[profile.guid()].push_back(
AutofillProfileDeepChange(AutofillProfileChange::ADD, profile));
+ if (enforced)
+ ongoing_profile_changes_[profile.guid()].back().set_enforced();
UpdateClientValidityStates(profile);
}
@@ -2606,11 +2491,11 @@ 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())) {
+ 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)) {
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
return;
}
}
@@ -2618,18 +2503,22 @@ void PersonalDataManager::UpdateProfileInDB(const AutofillProfile& profile,
ongoing_profile_changes_[profile.guid()].push_back(
AutofillProfileDeepChange(AutofillProfileChange::UPDATE, profile));
if (enforced)
- ongoing_profile_changes_[profile.guid()].back().set_enforce_update();
+ ongoing_profile_changes_[profile.guid()].back().set_enforced();
UpdateClientValidityStates(profile);
}
void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
- bool profile_exists = FindByGUID<AutofillProfile>(web_profiles_, guid);
- if (!profile_exists && !ProfileChangesAreOnGoing(guid)) {
- NotifyPersonalDataChanged();
+ auto profile_it = FindElementByGUID<AutofillProfile>(web_profiles_, guid);
+ bool profile_exists = profile_it != web_profiles_.end();
+ if (!profile_exists && !ProfileChangesAreOngoing(guid)) {
+ NotifyPersonalDataObserver();
return;
}
- AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, guid);
- if (!ProfileChangesAreOnGoing(guid)) {
+ const AutofillProfile* profile =
+ profile_exists ? profile_it->get()
+ : ongoing_profile_changes_[guid].back().profile();
+ AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, *profile);
+ if (!ProfileChangesAreOngoing(guid)) {
database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid);
change.set_is_ongoing_on_background();
}
@@ -2637,7 +2526,7 @@ void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) {
}
void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
- if (!ProfileChangesAreOnGoing(guid))
+ if (!ProfileChangesAreOngoing(guid))
return;
const auto& change = ongoing_profile_changes_[guid].front();
@@ -2665,7 +2554,8 @@ void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
return;
if (change_type == AutofillProfileChange::ADD) {
- if (profile_exists || FindByContents(web_profiles_, profile)) {
+ if (!change.enforced() &&
+ (profile_exists || FindByContents(web_profiles_, profile))) {
OnProfileChangeDone(guid);
return;
}
@@ -2674,7 +2564,7 @@ void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
return;
}
- if (profile_exists && (change.enforce_update() ||
+ if (profile_exists && (change.enforced() ||
!existing_profile->EqualsForUpdatePurposes(profile))) {
database_helper_->GetLocalDatabase()->UpdateAutofillProfile(profile);
change.set_is_ongoing_on_background();
@@ -2683,15 +2573,15 @@ void PersonalDataManager::HandleNextProfileChange(const std::string& guid) {
}
}
-bool PersonalDataManager::ProfileChangesAreOnGoing(const std::string& guid) {
+bool PersonalDataManager::ProfileChangesAreOngoing(const std::string& guid) {
return ongoing_profile_changes_.find(guid) !=
ongoing_profile_changes_.end() &&
!ongoing_profile_changes_[guid].empty();
}
-bool PersonalDataManager::ProfileChangesAreOnGoing() {
+bool PersonalDataManager::ProfileChangesAreOngoing() {
for (const auto& task : ongoing_profile_changes_) {
- if (ProfileChangesAreOnGoing(task.first)) {
+ if (ProfileChangesAreOngoing(task.first)) {
return true;
}
}
@@ -2701,10 +2591,10 @@ bool PersonalDataManager::ProfileChangesAreOnGoing() {
void PersonalDataManager::OnProfileChangeDone(const std::string& guid) {
ongoing_profile_changes_[guid].pop_front();
- if (!ProfileChangesAreOnGoing()) {
+ if (!ProfileChangesAreOngoing()) {
Refresh();
} else {
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
HandleNextProfileChange(guid);
}
}
diff --git a/chromium/components/autofill/core/browser/personal_data_manager.h b/chromium/components/autofill/core/browser/personal_data_manager.h
index df97465f599..24e2e0107bd 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager.h
+++ b/chromium/components/autofill/core/browser/personal_data_manager.h
@@ -19,11 +19,11 @@
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
-#include "components/autofill/core/browser/account_info_getter.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_validator.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/payments/account_info_getter.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/proto/server.pb.h"
#include "components/autofill/core/browser/suggestion.h"
@@ -111,7 +111,8 @@ class PersonalDataManager : public KeyedService,
std::unique_ptr<WDTypedResult> result) override;
// AutofillWebDataServiceObserverOnUISequence:
- void AutofillMultipleChanged() override;
+ void AutofillMultipleChangedBySync() override;
+ void AutofillAddressConversionCompleted() override;
void SyncStarted(syncer::ModelType model_type) override;
// SyncServiceObserver:
@@ -351,9 +352,6 @@ class PersonalDataManager : public KeyedService,
static void DedupeCreditCardToSuggest(
std::list<CreditCard*>* cards_to_suggest);
- // Notifies test observers that personal data has changed.
- void NotifyPersonalDataChangedForTest() { NotifyPersonalDataChanged(); }
-
// Cancels any pending queries to the server web database.
void CancelPendingServerQueries();
@@ -386,6 +384,9 @@ class PersonalDataManager : public KeyedService,
// Records the sync transport consent if the user is in sync transport mode.
virtual void OnUserAcceptedUpstreamOffer();
+ // Notifies observers that the waiting should be stopped.
+ void NotifyPersonalDataObserver();
+
void set_client_profile_validator_for_test(
AutofillProfileValidator* validator) {
client_profile_validator_ = validator;
@@ -519,9 +520,6 @@ class PersonalDataManager : public KeyedService,
// to the query handle.
void CancelPendingServerQuery(WebDataServiceBase::Handle* handle);
- // Notifies observers that personal data has changed.
- void NotifyPersonalDataChanged();
-
// The first time this is called, logs a UMA metrics about the user's autofill
// addresses. On subsequent calls, does nothing.
void LogStoredProfileMetrics() const;
@@ -721,10 +719,9 @@ class PersonalDataManager : public KeyedService,
// Resets |synced_profile_validity_|.
void ResetProfileValidity();
- // Add/Update/Remove |profile| on DB.
- void AddProfileToDB(const AutofillProfile& profile);
- // |enforced| is true when the update should happen regardless of an equal
- // profile. (equal in the sense of AutofillProfile::EqualForUpdate)
+ // Add/Update/Remove |profile| on DB. |enforced| should be true when the
+ // add/update should happen regardless of an existing/equal profile.
+ void AddProfileToDB(const AutofillProfile& profile, bool enforced = false);
void UpdateProfileInDB(const AutofillProfile& profile, bool enforced = false);
void RemoveProfileFromDB(const std::string& guid);
@@ -734,11 +731,11 @@ class PersonalDataManager : public KeyedService,
// Look at the next profile change for profile with guid = |guid|, and handle
// it.
void HandleNextProfileChange(const std::string& guid);
- // returns true if there is any profile change that's still on going.
- bool ProfileChangesAreOnGoing();
+ // returns true if there is any profile change that's still ongoing.
+ bool ProfileChangesAreOngoing();
// returns true if there is any ongoing change for profile with guid = |guid|
- // that's still on going.
- bool ProfileChangesAreOnGoing(const std::string& guid);
+ // that's still ongoing.
+ bool ProfileChangesAreOngoing(const std::string& guid);
// Remove the change from the |ongoing_profile_changes_|, handle next task or
// Refresh.
void OnProfileChangeDone(const std::string& guid);
@@ -766,7 +763,7 @@ class PersonalDataManager : public KeyedService,
// |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.
+ // A timely ordered list of ongoing changes for each profile.
std::unordered_map<std::string, std::deque<AutofillProfileDeepChange>>
ongoing_profile_changes_;
@@ -801,9 +798,6 @@ class PersonalDataManager : public KeyedService,
// True if autofill profile cleanup needs to be performed.
bool is_autofill_profile_cleanup_pending_ = false;
- // Whether new information was received from the sync server.
- bool has_synced_new_data_ = false;
-
// Used to create test data. If the AutofillCreateDataForTest feature is
// enabled, this helper creates autofill profiles and credit card data that
// would otherwise be difficult to create manually using the UI.
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 20fb473789c..7a49029d808 100644
--- a/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/chromium/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -38,6 +38,7 @@
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/label_formatter_utils.h"
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "components/autofill/core/browser/suggestion_selection.h"
#include "components/autofill/core/browser/sync_utils.h"
@@ -526,14 +527,10 @@ class PersonalDataManagerHelper : public PersonalDataManagerTestBase {
}
void ConvertWalletAddressesAndUpdateWalletCards() {
- 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_->ConvertWalletAddressesAndUpdateWalletCards();
- run_loop.Run();
+ // Simulate new data is coming from sync which triggers a conversion of
+ // wallet addresses which in turn triggers a refresh.
+ personal_data_->AutofillMultipleChangedBySync();
+ WaitForOnPersonalDataChanged();
}
std::unique_ptr<PersonalDataManager> personal_data_;
@@ -2229,10 +2226,6 @@ TEST_F(PersonalDataManagerTest,
ResetPersonalDataManager(USER_MODE_NORMAL);
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillSuppressDisusedAddresses);
-
// Query with empty string only returns profile2.
{
std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
@@ -2270,23 +2263,6 @@ TEST_F(PersonalDataManagerTest,
base::ASCIIToUTF16("456 Zoo St., Second Line, Third line, unit 5"),
suggestions[0].value);
}
-
- // When suppression is disabled, returns all suggestions.
- {
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillSuppressDisusedAddresses);
- std::vector<Suggestion> suggestions = personal_data_->GetProfileSuggestions(
- AutofillType(ADDRESS_HOME_STREET_ADDRESS), base::string16(), false,
- std::vector<ServerFieldType>());
- ASSERT_EQ(2U, suggestions.size());
- EXPECT_EQ(
- base::ASCIIToUTF16("456 Zoo St., Second Line, Third line, unit 5"),
- suggestions[0].value);
- EXPECT_EQ(
- base::ASCIIToUTF16("123 Zoo St., Second Line, Third line, unit 5"),
- suggestions[1].value);
- }
}
// Tests that suggestions based on invalid data are handled correctly.
@@ -2294,7 +2270,7 @@ 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));
+ base::TimeDelta::FromDays(1));
valid_profile.set_use_count(1);
AddProfileToPersonalDataManager(valid_profile);
@@ -2303,8 +2279,9 @@ TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
"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);
+ invalid_profile.set_use_date(AutofillClock::Now() -
+ base::TimeDelta::FromDays(1));
+ invalid_profile.set_use_count(1);
AddProfileToPersonalDataManager(invalid_profile);
auto profiles = personal_data_->GetProfiles();
@@ -2317,7 +2294,7 @@ TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileServerValidation,
features::kAutofillProfileClientValidation},
- /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses});
+ /*disabled_features=*/{});
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
base::string16(), false,
@@ -2366,7 +2343,7 @@ TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileClientValidation,
features::kAutofillProfileServerValidation},
- /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses});
+ /*disabled_features=*/{});
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
@@ -2396,8 +2373,7 @@ TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
base::test::ScopedFeatureList scoped_features;
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileClientValidation},
- /*disabled_features=*/{features::kAutofillSuppressDisusedAddresses,
- features::kAutofillProfileServerValidation});
+ /*disabled_features=*/{features::kAutofillProfileServerValidation});
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
base::string16(), false,
@@ -2427,9 +2403,7 @@ TEST_F(PersonalDataManagerTest, GetProfileSuggestions_Validity) {
base::test::ScopedFeatureList scoped_features;
scoped_features.InitWithFeatures(
/*enabled_features=*/{features::kAutofillProfileServerValidation},
- /*disabled_features=*/{features::kAutofillProfileClientValidation,
- features::kAutofillSuppressDisusedAddresses});
- LOG(ERROR) << __FUNCTION__;
+ /*disabled_features=*/{features::kAutofillProfileClientValidation});
std::vector<Suggestion> email_suggestions =
personal_data_->GetProfileSuggestions(AutofillType(EMAIL_ADDRESS),
base::string16(), false,
@@ -2570,6 +2544,216 @@ TEST_F(PersonalDataManagerTest,
EXPECT_EQ(0U, personal_data_->GetProfiles().size());
}
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForContactForm) {
+ AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
+ "401 Merrimack St", "", "Lowell", "MA", "01852", "US",
+ "19786744120");
+ AddProfileToPersonalDataManager(profile);
+
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillUseImprovedLabelDisambiguation);
+
+ EXPECT_THAT(
+ personal_data_->GetProfileSuggestions(
+ AutofillType(NAME_FIRST), base::string16(), false,
+ std::vector<ServerFieldType>{NAME_FIRST, NAME_LAST, EMAIL_ADDRESS,
+ PHONE_HOME_WHOLE_NUMBER}),
+ ElementsAre(AllOf(
+ testing::Field(
+ &Suggestion::label,
+ ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
+ base::ASCIIToUTF16("hoa.pham@comcast.net")})),
+ testing::Field(
+ &Suggestion::additional_label,
+ ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
+ base::ASCIIToUTF16("hoa.pham@comcast.net")})),
+ testing::Field(&Suggestion::icon, "accountBoxIcon"))));
+}
+#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForAddressForm) {
+ AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
+ "401 Merrimack St", "", "Lowell", "MA", "01852", "US",
+ "19786744120");
+ AddProfileToPersonalDataManager(profile);
+
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillUseImprovedLabelDisambiguation);
+
+ EXPECT_THAT(personal_data_->GetProfileSuggestions(
+ AutofillType(NAME_FULL), base::string16(), false,
+ std::vector<ServerFieldType>{
+ NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, ADDRESS_HOME_CITY,
+ ADDRESS_HOME_STATE, ADDRESS_HOME_ZIP}),
+ ElementsAre(AllOf(
+ testing::Field(
+ &Suggestion::label,
+ base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")),
+ testing::Field(
+ &Suggestion::additional_label,
+ base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")),
+ testing::Field(&Suggestion::icon, "accountBoxIcon"))));
+}
+#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForAddressPhoneForm) {
+ AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
+ "401 Merrimack St", "", "Lowell", "MA", "01852", "US",
+ "19786744120");
+ AddProfileToPersonalDataManager(profile);
+
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillUseImprovedLabelDisambiguation);
+
+ EXPECT_THAT(
+ personal_data_->GetProfileSuggestions(
+ AutofillType(NAME_FULL), base::string16(), false,
+ std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
+ PHONE_HOME_WHOLE_NUMBER}),
+ ElementsAre(AllOf(
+ testing::Field(
+ &Suggestion::label,
+ ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
+ base::ASCIIToUTF16("401 Merrimack St")})),
+ testing::Field(
+ &Suggestion::additional_label,
+ ConstructLabelLine({base::ASCIIToUTF16("(978) 674-4120"),
+ base::ASCIIToUTF16("401 Merrimack St")})),
+ testing::Field(&Suggestion::icon, "accountBoxIcon"))));
+}
+#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+TEST_F(PersonalDataManagerTest, GetProfileSuggestions_ForAddressEmailForm) {
+ AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
+ "401 Merrimack St", "", "Lowell", "MA", "01852", "US",
+ "19786744120");
+ AddProfileToPersonalDataManager(profile);
+
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillUseImprovedLabelDisambiguation);
+
+ EXPECT_THAT(
+ personal_data_->GetProfileSuggestions(
+ AutofillType(NAME_FULL), base::string16(), false,
+ std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
+ EMAIL_ADDRESS}),
+ ElementsAre(AllOf(
+ testing::Field(
+ &Suggestion::label,
+ ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St"),
+ base::ASCIIToUTF16("hoa.pham@comcast.net")})),
+ testing::Field(
+ &Suggestion::additional_label,
+ ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St"),
+ base::ASCIIToUTF16("hoa.pham@comcast.net")})),
+ testing::Field(&Suggestion::icon, "accountBoxIcon"))));
+}
+#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+TEST_F(PersonalDataManagerTest, GetProfileSuggestions_FormWithOneProfile) {
+ AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
+ "401 Merrimack St", "", "Lowell", "MA", "01852", "US",
+ "19786744120");
+ AddProfileToPersonalDataManager(profile);
+
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillUseImprovedLabelDisambiguation);
+
+ EXPECT_THAT(
+ personal_data_->GetProfileSuggestions(
+ AutofillType(NAME_FULL), base::string16(), false,
+ std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
+ EMAIL_ADDRESS, PHONE_HOME_WHOLE_NUMBER}),
+ ElementsAre(AllOf(
+ testing::Field(
+ &Suggestion::label,
+ ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St")})),
+ testing::Field(
+ &Suggestion::additional_label,
+ ConstructLabelLine({base::ASCIIToUTF16("401 Merrimack St")})),
+ testing::Field(&Suggestion::icon, "accountBoxIcon"))));
+}
+#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+TEST_F(PersonalDataManagerTest,
+ GetProfileSuggestions_ForAddressContactFormWithProfiles) {
+ AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile1, "Hoa", "", "Pham", "hoa.pham@comcast.net", "",
+ "401 Merrimack St", "", "Lowell", "MA", "01852", "US",
+ "19786744120");
+
+ AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
+ test::SetProfileInfo(&profile2, "Hoa", "", "Pham", "hp@aol.com", "",
+ "216 Broadway St", "", "Lowell", "MA", "01854", "US",
+ "19784523366");
+
+ // The profiles' use dates and counts are set make this test deterministic.
+ // The suggestion created with data from profile1 should be ranked higher
+ // than profile2's associated suggestion. This ensures that profile1's
+ // suggestion is the first element in the collection returned by
+ // GetProfileSuggestions.
+ profile1.set_use_date(AutofillClock::Now());
+ profile1.set_use_count(10);
+ profile2.set_use_date(AutofillClock::Now() - base::TimeDelta::FromDays(10));
+ profile2.set_use_count(1);
+
+ EXPECT_TRUE(profile1.HasGreaterFrecencyThan(&profile2, base::Time::Now()));
+
+ AddProfileToPersonalDataManager(profile1);
+ AddProfileToPersonalDataManager(profile2);
+
+ base::test::ScopedFeatureList scoped_features;
+ scoped_features.InitAndEnableFeature(
+ features::kAutofillUseImprovedLabelDisambiguation);
+
+ EXPECT_THAT(
+ personal_data_->GetProfileSuggestions(
+ AutofillType(NAME_FULL), base::string16(), false,
+ std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS,
+ EMAIL_ADDRESS, PHONE_HOME_WHOLE_NUMBER}),
+ ElementsAre(
+ AllOf(
+ testing::Field(&Suggestion::label,
+ ConstructLabelLine(
+ {base::ASCIIToUTF16("401 Merrimack St"),
+ base::ASCIIToUTF16("(978) 674-4120"),
+ base::ASCIIToUTF16("hoa.pham@comcast.net")})),
+ testing::Field(&Suggestion::additional_label,
+ ConstructLabelLine(
+ {base::ASCIIToUTF16("401 Merrimack St"),
+ base::ASCIIToUTF16("(978) 674-4120"),
+ base::ASCIIToUTF16("hoa.pham@comcast.net")})),
+ testing::Field(&Suggestion::icon, "accountBoxIcon")),
+ AllOf(testing::Field(
+ &Suggestion::label,
+ ConstructLabelLine({base::ASCIIToUTF16("216 Broadway St"),
+ base::ASCIIToUTF16("(978) 452-3366"),
+ base::ASCIIToUTF16("hp@aol.com")})),
+ testing::Field(
+ &Suggestion::additional_label,
+ ConstructLabelLine({base::ASCIIToUTF16("216 Broadway St"),
+ base::ASCIIToUTF16("(978) 452-3366"),
+ base::ASCIIToUTF16("hp@aol.com")})),
+ testing::Field(&Suggestion::icon, "accountBoxIcon"))));
+}
+#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS)
+
TEST_F(PersonalDataManagerTest, IsKnownCard_MatchesMaskedServerCard) {
// Add a masked server card.
std::vector<CreditCard> server_cards;
@@ -3081,27 +3265,6 @@ TEST_F(PersonalDataManagerTest,
WaitForOnPersonalDataChanged();
ASSERT_EQ(4U, personal_data_->GetCreditCards().size());
- // Verify no suppression if feature is disabled.
- {
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillSuppressDisusedCreditCards);
-
- std::vector<Suggestion> suggestions =
- personal_data_->GetCreditCardSuggestions(
- AutofillType(CREDIT_CARD_NAME_FULL), base::string16(),
- /*include_server_cards=*/true);
- EXPECT_EQ(4U, suggestions.size());
- EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[0].value);
- EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value);
- EXPECT_EQ(base::ASCIIToUTF16("Jane Doe"), suggestions[2].value);
- EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[3].value);
- }
-
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillSuppressDisusedCreditCards);
-
// Query with empty string only returns card0 and card1. Note expired
// masked card2 is not suggested on empty fields.
{
@@ -5079,31 +5242,10 @@ TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_OncePerVersion) {
EXPECT_EQ(2U, personal_data_->GetProfiles().size());
}
-// Tests that DeleteDisusedAddresses is not run if the feature is disabled.
-TEST_F(PersonalDataManagerTest, DeleteDisusedAddresses_DoNothingWhenDisabled) {
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillDeleteDisusedAddresses);
-
- CreateDeletableDisusedProfile();
-
- // DeleteDisusedCreditCards should return false to indicate it was not run.
- EXPECT_FALSE(personal_data_->DeleteDisusedAddresses());
-
- personal_data_->Refresh();
-
- EXPECT_EQ(1U, personal_data_->GetProfiles().size());
-}
-
// Tests that DeleteDisusedAddresses only deletes the addresses that are
// supposed to be deleted.
TEST_F(PersonalDataManagerTest,
DeleteDisusedAddresses_DeleteDesiredAddressesOnly) {
- // Enable the feature.
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillDeleteDisusedAddresses);
-
auto now = AutofillClock::Now();
// Create unverified/disused/not-used-by-valid-credit-card
@@ -5182,31 +5324,9 @@ TEST_F(PersonalDataManagerTest,
personal_data_->GetProfiles()[2]->GetRawInfo(NAME_LAST));
}
-// Tests that DeleteDisusedCreditCards is not run if the feature is disabled.
-TEST_F(PersonalDataManagerTest,
- DeleteDisusedCreditCards_DoNothingWhenDisabled) {
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndDisableFeature(
- features::kAutofillDeleteDisusedCreditCards);
-
- CreateDeletableExpiredAndDisusedCreditCard();
-
- // DeleteDisusedCreditCards should return false to indicate it was not run.
- EXPECT_FALSE(personal_data_->DeleteDisusedCreditCards());
-
- personal_data_->Refresh();
-
- EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
-}
-
// Tests that DeleteDisusedCreditCards deletes desired credit cards only.
TEST_F(PersonalDataManagerTest,
DeleteDisusedCreditCards_OnlyDeleteExpiredDisusedLocalCards) {
- // Enable the feature.
- base::test::ScopedFeatureList scoped_features;
- scoped_features.InitAndEnableFeature(
- features::kAutofillDeleteDisusedCreditCards);
-
const char kHistogramName[] = "Autofill.CreditCardsDeletedForDisuse";
auto now = AutofillClock::Now();
@@ -5563,14 +5683,7 @@ TEST_F(PersonalDataManagerTest,
///////////////////////////////////////////////////////////////////////
// Tested method.
///////////////////////////////////////////////////////////////////////
- personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
-
- // Since there should be no change in data, OnPersonalDataChanged should not
- // have been called.
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
-
- personal_data_->Refresh();
- WaitForOnPersonalDataChanged();
+ ConvertWalletAddressesAndUpdateWalletCards();
// There should be no local profiles added.
EXPECT_EQ(0U, personal_data_->GetProfiles().size());
@@ -5841,18 +5954,11 @@ TEST_F(PersonalDataManagerTest, DoNotConvertWalletAddressesInEphemeralStorage) {
///////////////////////////////////////////////////////////////////////
// Since the wallet addresses are in ephemeral storage, they should *not* get
// converted to local addresses.
- personal_data_->ConvertWalletAddressesAndUpdateWalletCards();
+ ConvertWalletAddressesAndUpdateWalletCards();
///////////////////////////////////////////////////////////////////////
// Validation.
///////////////////////////////////////////////////////////////////////
- // Since there should be no change in data, OnPersonalDataChanged should not
- // get called.
- EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()).Times(0);
-
- personal_data_->Refresh();
- WaitForOnPersonalDataChanged();
-
// There should be no changes to the local profiles: No new one added, and no
// changes to the existing one (even though the second server profile contains
// additional information and is mergeable in principle).
@@ -7662,7 +7768,7 @@ TEST_F(PersonalDataManagerTest, GetSyncSigninState) {
// Check that the sync state is |SignedInAndSyncFeature| if the sync feature
// is enabled.
- EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeature,
+ EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled,
personal_data_->GetSyncSigninState());
// Check that the sync state is |SignedInAndSyncFeature| if the the sync
@@ -7674,7 +7780,7 @@ TEST_F(PersonalDataManagerTest, GetSyncSigninState) {
/*enabled_features=*/{features::kAutofillEnableAccountWalletStorage,
features::kAutofillGetPaymentsIdentityFromSync},
/*disabled_features=*/{});
- EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeature,
+ EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled,
personal_data_->GetSyncSigninState());
}
}
@@ -7760,7 +7866,7 @@ TEST_F(PersonalDataManagerTest, OnUserAcceptedUpstreamOffer) {
identity_test_env_.SetPrimaryAccount(active_info.email);
sync_service_.SetIsAuthenticatedAccountPrimary(true);
{
- EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeature,
+ EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled,
personal_data_->GetSyncSigninState());
// Make sure an opt-in does not get recorded even if the user accepted an
diff --git a/chromium/components/autofill/core/browser/phone_number.cc b/chromium/components/autofill/core/browser/phone_number.cc
index f60a58b5d42..7498365f806 100644
--- a/chromium/components/autofill/core/browser/phone_number.cc
+++ b/chromium/components/autofill/core/browser/phone_number.cc
@@ -31,7 +31,7 @@ std::string GetRegion(const AutofillProfile& profile,
} // namespace
-PhoneNumber::PhoneNumber(AutofillProfile* profile) : profile_(profile) {}
+PhoneNumber::PhoneNumber(const AutofillProfile* profile) : profile_(profile) {}
PhoneNumber::PhoneNumber(const PhoneNumber& number) : profile_(nullptr) {
*this = number;
diff --git a/chromium/components/autofill/core/browser/phone_number.h b/chromium/components/autofill/core/browser/phone_number.h
index 4773e8cb34c..ab350f3201d 100644
--- a/chromium/components/autofill/core/browser/phone_number.h
+++ b/chromium/components/autofill/core/browser/phone_number.h
@@ -21,7 +21,7 @@ class AutofillProfile;
// A form group that stores phone number information.
class PhoneNumber : public FormGroup {
public:
- explicit PhoneNumber(AutofillProfile* profile);
+ explicit PhoneNumber(const AutofillProfile* profile);
PhoneNumber(const PhoneNumber& number);
~PhoneNumber() override;
@@ -29,7 +29,7 @@ class PhoneNumber : public FormGroup {
bool operator==(const PhoneNumber& other) const;
bool operator!=(const PhoneNumber& other) const { return !operator==(other); }
- void set_profile(AutofillProfile* profile) { profile_ = profile; }
+ void set_profile(const AutofillProfile* profile) { profile_ = profile; }
// FormGroup implementation:
void GetMatchingTypes(const base::string16& text,
diff --git a/chromium/components/autofill/core/browser/phone_number_i18n.cc b/chromium/components/autofill/core/browser/phone_number_i18n.cc
index 956eed000e7..ecfbe9ad12e 100644
--- a/chromium/components/autofill/core/browser/phone_number_i18n.cc
+++ b/chromium/components/autofill/core/browser/phone_number_i18n.cc
@@ -265,6 +265,8 @@ bool PhoneNumbersMatch(const base::string16& number_a,
const base::string16& number_b,
const std::string& raw_region,
const std::string& app_locale) {
+ // TODO(crbug.com/953678): Maybe return true if two empty strings are given.
+
// Sanitize the provided |raw_region| before trying to use it for parsing.
const std::string region = SanitizeRegion(raw_region, app_locale);
diff --git a/chromium/components/autofill/core/browser/proto/api_v1.proto b/chromium/components/autofill/core/browser/proto/api_v1.proto
index d19c41905d6..0b26c68c576 100644
--- a/chromium/components/autofill/core/browser/proto/api_v1.proto
+++ b/chromium/components/autofill/core/browser/proto/api_v1.proto
@@ -24,7 +24,7 @@ message AutofillPageResourceQueryRequest {
// Request to retrieve field suggestions for multiple forms in a page. You can
// see this as batched form requests.
-// Next ID: 3
+// Next ID: 4
message AutofillPageQueryRequest {
// Next ID: 3
message Form {
@@ -54,6 +54,8 @@ message AutofillPageQueryRequest {
optional string client_version = 1 [deprecated = true];
// Forms in the same page for which we want fields suggestions.
repeated Form forms = 2;
+ // The collection of server-side experiments to use.
+ repeated int64 experiments = 3;
};
// Response containing field suggestions from Autofill API for
diff --git a/chromium/components/autofill/core/browser/proto/legacy_proto_bridge.cc b/chromium/components/autofill/core/browser/proto/legacy_proto_bridge.cc
index 3bd19b491aa..9ce166cb9dc 100644
--- a/chromium/components/autofill/core/browser/proto/legacy_proto_bridge.cc
+++ b/chromium/components/autofill/core/browser/proto/legacy_proto_bridge.cc
@@ -56,6 +56,7 @@ AutofillQueryResponseContents::Field CreateLegacyFieldFromApiField(
AutofillPageQueryRequest CreateApiRequestFromLegacyRequest(
const AutofillQueryContents& legacy_request) {
AutofillPageQueryRequest api_request;
+ *api_request.mutable_experiments() = legacy_request.experiments();
api_request.set_client_version(legacy_request.client_version());
for (const auto& legacy_form : legacy_request.form()) {
*api_request.add_forms() = CreateApiFormFromLegacyForm(legacy_form);
diff --git a/chromium/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc b/chromium/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc
index bd875b3931d..6c4f791dd1c 100644
--- a/chromium/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/proto/legacy_proto_bridge_unittest.cc
@@ -70,6 +70,8 @@ AutofillQueryResponse::FormSuggestion::FieldSuggestion MakeFieldSuggestion(
TEST(ProtoBridgeTest, TestCreateApiRequestFromLegacyRequest) {
AutofillQueryContents legacy_request;
legacy_request.set_client_version("dummy client v1");
+ legacy_request.add_experiments(1234);
+ legacy_request.add_experiments(5678);
AutofillQueryContents::Form* new_form = legacy_request.add_form();
new_form->set_signature(1234U);
*new_form->mutable_form_metadata() = GetformMetadata();
@@ -86,6 +88,8 @@ TEST(ProtoBridgeTest, TestCreateApiRequestFromLegacyRequest) {
CreateApiRequestFromLegacyRequest(legacy_request);
EXPECT_EQ(api_request.client_version(), "dummy client v1");
+ EXPECT_EQ(api_request.experiments(0), 1234);
+ EXPECT_EQ(api_request.experiments(1), 5678);
EXPECT_EQ(api_request.forms(0).signature(), 1234U);
EXPECT_EQ(api_request.forms(0).metadata().id().encoding_type(),
AutofillRandomizedValue::BIT_1);
diff --git a/chromium/components/autofill/core/browser/proto/server.proto b/chromium/components/autofill/core/browser/proto/server.proto
index 86bc91e222d..02f57c7440e 100644
--- a/chromium/components/autofill/core/browser/proto/server.proto
+++ b/chromium/components/autofill/core/browser/proto/server.proto
@@ -186,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: 39
+// Next available id: 40
message AutofillUploadContents {
required string client_version = 1;
required fixed64 form_signature = 2;
@@ -343,6 +343,13 @@ message AutofillUploadContents {
// Noisifed password length.
optional uint32 password_length = 29;
+
+ // If |password_has_special_symbol| is true, this field contains nosified
+ // information about a special symbol used in a user-created password stored
+ // in ASCII code.
+ // Otherwise, this field is unset.
+ optional uint32 password_special_symbol = 39;
+
// The end of the section of password attributes.
// Event observed by the password manager which indicated that the form was
diff --git a/chromium/components/autofill/core/browser/suggestion_selection.cc b/chromium/components/autofill/core/browser/suggestion_selection.cc
index 0a8d6c04a10..05fd1c4b25c 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection.cc
+++ b/chromium/components/autofill/core/browser/suggestion_selection.cc
@@ -9,7 +9,9 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "components/autofill/core/browser/address_i18n.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_comparator.h"
@@ -84,6 +86,22 @@ std::vector<Suggestion> GetPrefixMatchedSuggestions(
suggestion_canon, field_contents_canon, type,
/* is_masked_server_card= */ false, &prefix_matched_suggestion)) {
matched_profiles->push_back(profile);
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ // If the field with which the user is interacting is a phone number or
+ // part of a phone number, then display it in the national format
+ // corresponding to the profile's country. For example, (508) 488-0800
+ // will be shown rather than 15084880800, 508 488 0800, or +15084880800
+ // for US phone numbers.
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillUseImprovedLabelDisambiguation) &&
+ type.group() == PHONE_HOME) {
+ value = base::UTF8ToUTF16(i18n::FormatPhoneNationallyForDisplay(
+ base::UTF16ToUTF8(value), data_util::GetCountryCodeWithFallback(
+ *profile, comparator.app_locale())));
+ }
+#endif
+
suggestions.push_back(Suggestion(value));
suggestions.back().backend_id = profile->guid();
suggestions.back().match = prefix_matched_suggestion
@@ -204,5 +222,23 @@ void RemoveProfilesNotUsedSinceTimestamp(
num_profiles_supressed);
}
+void PrepareSuggestions(bool contains_address,
+ const std::vector<base::string16>& labels,
+ std::vector<Suggestion>* suggestions) {
+ DCHECK_EQ(suggestions->size(), labels.size());
+
+ for (size_t i = 0; i < labels.size(); ++i) {
+ (*suggestions)[i].additional_label = base::string16(labels[i]);
+ (*suggestions)[i].label = base::string16(labels[i]);
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ if (base::FeatureList::IsEnabled(
+ autofill::features::kAutofillUseImprovedLabelDisambiguation)) {
+ (*suggestions)[i].icon = "accountBoxIcon";
+ }
+#endif
+ }
+}
+
} // namespace suggestion_selection
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/suggestion_selection.h b/chromium/components/autofill/core/browser/suggestion_selection.h
index 0e6909e4c51..817c0d20756 100644
--- a/chromium/components/autofill/core/browser/suggestion_selection.h
+++ b/chromium/components/autofill/core/browser/suggestion_selection.h
@@ -59,6 +59,15 @@ void RemoveProfilesNotUsedSinceTimestamp(
base::Time min_last_used,
std::vector<AutofillProfile*>* profiles);
+// Prepares a collection of Suggestions to show to the user. Adds |labels| to
+// their corresponding |suggestions|. A label corresponds to the suggestion with
+// the same index.
+// |contains_address| determines which icon to add to suggestions in the
+// autofill-use-improved-label-disambiguation experiment.
+void PrepareSuggestions(bool contains_address,
+ const std::vector<base::string16>& labels,
+ std::vector<Suggestion>* suggestions);
+
} // namespace suggestion_selection
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/sync_utils.h b/chromium/components/autofill/core/browser/sync_utils.h
index 2774bedb055..1024c4072b7 100644
--- a/chromium/components/autofill/core/browser/sync_utils.h
+++ b/chromium/components/autofill/core/browser/sync_utils.h
@@ -18,7 +18,10 @@ enum AutofillSyncSigninState {
kSignedInAndWalletSyncTransportEnabled,
// The user is signed in, has enabled the sync feature and has not disabled
// Wallet sync.
- kSignedInAndSyncFeature,
+ kSignedInAndSyncFeatureEnabled,
+ // The user has enabled the sync feature, but has then signed out, so sync is
+ // paused.
+ kSyncPaused,
kNumSyncStates,
};
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.cc b/chromium/components/autofill/core/browser/test_autofill_client.cc
index dadbbd1dfed..fe92b8c4974 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.cc
+++ b/chromium/components/autofill/core/browser/test_autofill_client.cc
@@ -7,7 +7,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/payments/local_card_migration_manager.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
namespace autofill {
diff --git a/chromium/components/autofill/core/browser/test_autofill_client.h b/chromium/components/autofill/core/browser/test_autofill_client.h
index 71baad73db0..70217e9ffff 100644
--- a/chromium/components/autofill/core/browser/test_autofill_client.h
+++ b/chromium/components/autofill/core/browser/test_autofill_client.h
@@ -16,12 +16,12 @@
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/mock_autocomplete_history_manager.h"
+#include "components/autofill/core/browser/payments/test_legacy_strike_database.h"
#include "components/autofill/core/browser/payments/test_payments_client.h"
+#include "components/autofill/core/browser/payments/test_strike_database.h"
#include "components/autofill/core/browser/test_address_normalizer.h"
#include "components/autofill/core/browser/test_form_data_importer.h"
-#include "components/autofill/core/browser/test_legacy_strike_database.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
-#include "components/autofill/core/browser/test_strike_database.h"
#include "components/prefs/pref_service.h"
#include "components/ukm/test_ukm_recorder.h"
#include "services/identity/public/cpp/identity_test_environment.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 209cf497334..f1d48c3d9bc 100644
--- a/chromium/components/autofill/core/browser/test_personal_data_manager.cc
+++ b/chromium/components/autofill/core/browser/test_personal_data_manager.cc
@@ -50,7 +50,7 @@ void TestPersonalDataManager::AddProfile(const AutofillProfile& profile) {
std::unique_ptr<AutofillProfile> profile_ptr =
std::make_unique<AutofillProfile>(profile);
web_profiles_.push_back(std::move(profile_ptr));
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
}
void TestPersonalDataManager::UpdateProfile(const AutofillProfile& profile) {
@@ -86,7 +86,7 @@ void TestPersonalDataManager::AddCreditCard(const CreditCard& credit_card) {
std::unique_ptr<CreditCard> local_credit_card =
std::make_unique<CreditCard>(credit_card);
local_credit_cards_.push_back(std::move(local_credit_card));
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
}
void TestPersonalDataManager::DeleteLocalCreditCards(
@@ -94,7 +94,7 @@ void TestPersonalDataManager::DeleteLocalCreditCards(
for (const auto& card : cards)
RemoveByGUID(card.guid());
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
}
void TestPersonalDataManager::UpdateCreditCard(const CreditCard& credit_card) {
@@ -287,7 +287,7 @@ void TestPersonalDataManager::AddServerCreditCard(
std::unique_ptr<CreditCard> server_credit_card =
std::make_unique<CreditCard>(credit_card);
server_credit_cards_.push_back(std::move(server_credit_card));
- NotifyPersonalDataChanged();
+ NotifyPersonalDataObserver();
}
} // namespace autofill
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 8aedd182f36..0dd399b004b 100644
--- a/chromium/components/autofill/core/browser/test_personal_data_manager.h
+++ b/chromium/components/autofill/core/browser/test_personal_data_manager.h
@@ -135,7 +135,7 @@ class TestPersonalDataManager : public PersonalDataManager {
base::Optional<bool> autofill_wallet_import_enabled_;
bool sync_feature_enabled_ = false;
AutofillSyncSigninState sync_and_signin_state_ =
- AutofillSyncSigninState::kSignedInAndSyncFeature;
+ AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled;
bool sync_service_initialized_ = false;
CoreAccountInfo account_info_;
diff --git a/chromium/components/autofill/core/browser/ui/DEPS b/chromium/components/autofill/core/browser/ui/payments/DEPS
index ed07b2dd031..ed07b2dd031 100644
--- a/chromium/components/autofill/core/browser/ui/DEPS
+++ b/chromium/components/autofill/core/browser/ui/payments/DEPS
diff --git a/chromium/components/autofill/core/browser/ui/payments/OWNERS b/chromium/components/autofill/core/browser/ui/payments/OWNERS
new file mode 100644
index 00000000000..a6f6a368d86
--- /dev/null
+++ b/chromium/components/autofill/core/browser/ui/payments/OWNERS
@@ -0,0 +1 @@
+file://components/autofill/core/browser/payments/OWNERS
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/payments/card_expiration_date_fix_flow_view_delegate_mobile.cc
index 812c157cc11..f60bd3e41df 100644
--- a/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_view_delegate_mobile.cc
@@ -2,7 +2,7 @@
// 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 "components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_view_delegate_mobile.h"
#include <utility>
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/payments/card_expiration_date_fix_flow_view_delegate_mobile.h
index d749b79ad1f..fcc6e3afb7b 100644
--- a/chromium/components/autofill/core/browser/ui/card_expiration_date_fix_flow_view_delegate_mobile.h
+++ b/chromium/components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_view_delegate_mobile.h
@@ -2,8 +2,8 @@
// 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_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
#include <memory>
@@ -57,4 +57,4 @@ class CardExpirationDateFixFlowViewDelegateMobile {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_EXPIRATION_DATE_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_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/payments/card_name_fix_flow_view_delegate_mobile.cc
index c5d3b1f8980..aebe3e2cdad 100644
--- a/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.cc
+++ b/chromium/components/autofill/core/browser/ui/payments/card_name_fix_flow_view_delegate_mobile.cc
@@ -2,7 +2,7 @@
// 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_name_fix_flow_view_delegate_mobile.h"
+#include "components/autofill/core/browser/ui/payments/card_name_fix_flow_view_delegate_mobile.h"
#include <utility>
diff --git a/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.h b/chromium/components/autofill/core/browser/ui/payments/card_name_fix_flow_view_delegate_mobile.h
index dcad3d0ee06..64415a44661 100644
--- a/chromium/components/autofill/core/browser/ui/card_name_fix_flow_view_delegate_mobile.h
+++ b/chromium/components/autofill/core/browser/ui/payments/card_name_fix_flow_view_delegate_mobile.h
@@ -2,8 +2,8 @@
// 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_NAME_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_NAME_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_NAME_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_NAME_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
#include <memory>
@@ -34,7 +34,6 @@ class CardNameFixFlowViewDelegateMobile {
void Shown();
private:
-
// Inferred cardholder name from Gaia account.
base::string16 inferred_cardholder_name_;
@@ -53,4 +52,4 @@ class CardNameFixFlowViewDelegateMobile {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_NAME_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_NAME_FIX_FLOW_VIEW_DELEGATE_MOBILE_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller.h b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
index 68e71be5927..b4c5da8a029 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller.h
+++ b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
@@ -2,8 +2,8 @@
// 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_UNMASK_PROMPT_CONTROLLER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_UNMASK_PROMPT_CONTROLLER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_CONTROLLER_H_
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_client.h"
@@ -44,4 +44,4 @@ class CardUnmaskPromptController {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_UNMASK_PROMPT_CONTROLLER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_CONTROLLER_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc
index 7a3c321db04..1015cfb9d56 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.cc
+++ b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc
@@ -2,7 +2,7 @@
// 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_unmask_prompt_controller_impl.h"
+#include "components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h"
#include <stddef.h>
@@ -14,9 +14,10 @@
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_metrics.h"
-#include "components/autofill/core/browser/ui/card_unmask_prompt_view.h"
+#include "components/autofill/core/browser/ui/payments/card_unmask_prompt_view.h"
#include "components/autofill/core/browser/validation.h"
#include "components/autofill/core/common/autofill_clock.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/grit/components_scaled_resources.h"
#include "components/prefs/pref_service.h"
@@ -94,8 +95,7 @@ void CardUnmaskPromptControllerImpl::OnVerificationResult(
AutofillMetrics::LogRealPanResult(result);
AutofillMetrics::LogUnmaskingDuration(
AutofillClock::Now() - verify_timestamp_, result);
- card_unmask_view_->GotVerificationResult(error_message,
- AllowsRetry(result));
+ card_unmask_view_->GotVerificationResult(error_message, AllowsRetry(result));
}
void CardUnmaskPromptControllerImpl::OnUnmaskDialogClosed() {
@@ -126,8 +126,8 @@ void CardUnmaskPromptControllerImpl::OnUnmaskResponse(
if (CanStoreLocally()) {
pending_response_.should_store_pan = should_store_pan;
// Remember the last choice the user made (on this device).
- pref_service_->SetBoolean(
- prefs::kAutofillWalletImportStorageCheckboxState, should_store_pan);
+ pref_service_->SetBoolean(prefs::kAutofillWalletImportStorageCheckboxState,
+ should_store_pan);
} else {
DCHECK(!should_store_pan);
pending_response_.should_store_pan = false;
@@ -198,6 +198,10 @@ bool CardUnmaskPromptControllerImpl::ShouldRequestExpirationDate() const {
}
bool CardUnmaskPromptControllerImpl::CanStoreLocally() const {
+ if (base::FeatureList::IsEnabled(
+ features::kAutofillNoLocalSaveOnUnmaskSuccess)) {
+ return false;
+ }
// Never offer to save for incognito.
if (is_off_the_record_)
return false;
@@ -205,6 +209,7 @@ bool CardUnmaskPromptControllerImpl::CanStoreLocally() const {
return false;
if (card_.record_type() == CreditCard::LOCAL_CARD)
return false;
+
return OfferStoreUnmaskedCards(is_off_the_record_);
}
@@ -254,7 +259,8 @@ base::TimeDelta CardUnmaskPromptControllerImpl::GetSuccessMessageDuration()
return base::TimeDelta::FromMilliseconds(
card_.record_type() == CreditCard::LOCAL_CARD ||
reason_ == AutofillClient::UNMASK_FOR_PAYMENT_REQUEST
- ? 0 : 500);
+ ? 0
+ : 500);
}
AutofillClient::PaymentsRpcResult
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h
index c7e3fb311f4..6a920e8e4b9 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h
+++ b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h
@@ -2,8 +2,8 @@
// 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_UNMASK_PROMPT_CONTROLLER_IMPL_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_
#include <string>
@@ -11,9 +11,9 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/autofill/core/browser/autofill_metrics.h"
-#include "components/autofill/core/browser/card_unmask_delegate.h"
#include "components/autofill/core/browser/credit_card.h"
-#include "components/autofill/core/browser/ui/card_unmask_prompt_controller.h"
+#include "components/autofill/core/browser/payments/card_unmask_delegate.h"
+#include "components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h"
namespace autofill {
@@ -21,9 +21,8 @@ class CardUnmaskPromptView;
class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController {
public:
- CardUnmaskPromptControllerImpl(
- PrefService* pref_service,
- bool is_off_the_record);
+ CardUnmaskPromptControllerImpl(PrefService* pref_service,
+ bool is_off_the_record);
virtual ~CardUnmaskPromptControllerImpl();
// Functions called by ChromeAutofillClient.
@@ -90,4 +89,4 @@ class CardUnmaskPromptControllerImpl : public CardUnmaskPromptController {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_CONTROLLER_IMPL_H_
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
index 9012160a9b2..c916a47fd12 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_controller_impl_unittest.cc
+++ b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
@@ -2,7 +2,7 @@
// 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_unmask_prompt_controller_impl.h"
+#include "components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h"
#include <stddef.h>
@@ -16,7 +16,8 @@
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/credit_card.h"
-#include "components/autofill/core/browser/ui/card_unmask_prompt_view.h"
+#include "components/autofill/core/browser/ui/payments/card_unmask_prompt_view.h"
+#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
@@ -65,7 +66,8 @@ class TestCardUnmaskPromptController : public CardUnmaskPromptControllerImpl {
explicit TestCardUnmaskPromptController(
TestingPrefServiceSimple* pref_service)
: CardUnmaskPromptControllerImpl(pref_service, false),
- can_store_locally_(true),
+ can_store_locally_(!base::FeatureList::IsEnabled(
+ features::kAutofillNoLocalSaveOnUnmaskSuccess)),
weak_factory_(this) {}
bool CanStoreLocally() const override { return can_store_locally_; }
@@ -92,35 +94,30 @@ class CardUnmaskPromptControllerImplGenericTest {
CardUnmaskPromptControllerImplGenericTest() {}
void ShowPrompt() {
- controller_->ShowPrompt(test_unmask_prompt_view_.get(),
- test::GetMaskedServerCard(),
- AutofillClient::UNMASK_FOR_AUTOFILL,
- delegate_->GetWeakPtr());
+ controller_->ShowPrompt(
+ test_unmask_prompt_view_.get(), test::GetMaskedServerCard(),
+ AutofillClient::UNMASK_FOR_AUTOFILL, delegate_->GetWeakPtr());
}
void ShowPromptAmex() {
- controller_->ShowPrompt(test_unmask_prompt_view_.get(),
- test::GetMaskedServerCardAmex(),
- AutofillClient::UNMASK_FOR_AUTOFILL,
- delegate_->GetWeakPtr());
+ controller_->ShowPrompt(
+ test_unmask_prompt_view_.get(), test::GetMaskedServerCardAmex(),
+ AutofillClient::UNMASK_FOR_AUTOFILL, delegate_->GetWeakPtr());
}
void ShowPromptAndSimulateResponse(bool should_store_pan) {
ShowPrompt();
- controller_->OnUnmaskResponse(ASCIIToUTF16("444"),
- ASCIIToUTF16("01"),
- ASCIIToUTF16("2050"),
- should_store_pan);
- EXPECT_EQ(
- should_store_pan,
- pref_service_->GetBoolean(
- prefs::kAutofillWalletImportStorageCheckboxState));
+ controller_->OnUnmaskResponse(ASCIIToUTF16("444"), ASCIIToUTF16("01"),
+ ASCIIToUTF16("2050"), should_store_pan);
+ EXPECT_EQ(should_store_pan,
+ pref_service_->GetBoolean(
+ prefs::kAutofillWalletImportStorageCheckboxState));
}
protected:
void SetImportCheckboxState(bool value) {
- pref_service_->SetBoolean(
- prefs::kAutofillWalletImportStorageCheckboxState, value);
+ pref_service_->SetBoolean(prefs::kAutofillWalletImportStorageCheckboxState,
+ value);
}
std::unique_ptr<TestCardUnmaskPromptView> test_unmask_prompt_view_;
@@ -156,9 +153,8 @@ TEST_F(CardUnmaskPromptControllerImplTest, LogShown) {
base::HistogramTester histogram_tester;
ShowPrompt();
- histogram_tester.ExpectUniqueSample(
- "Autofill.UnmaskPrompt.Events",
- AutofillMetrics::UNMASK_PROMPT_SHOWN, 1);
+ histogram_tester.ExpectUniqueSample("Autofill.UnmaskPrompt.Events",
+ AutofillMetrics::UNMASK_PROMPT_SHOWN, 1);
}
TEST_F(CardUnmaskPromptControllerImplTest, LogClosedNoAttempts) {
@@ -195,8 +191,7 @@ TEST_F(CardUnmaskPromptControllerImplTest, LogClosedFailedToUnmaskRetriable) {
histogram_tester.ExpectBucketCount(
"Autofill.UnmaskPrompt.Events",
- AutofillMetrics
- ::UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_RETRIABLE_FAILURE,
+ AutofillMetrics ::UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_RETRIABLE_FAILURE,
1);
}
@@ -214,8 +209,8 @@ TEST_F(CardUnmaskPromptControllerImplTest,
histogram_tester.ExpectBucketCount(
"Autofill.UnmaskPrompt.Events",
- AutofillMetrics
- ::UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_NON_RETRIABLE_FAILURE,
+ AutofillMetrics ::
+ UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_NON_RETRIABLE_FAILURE,
1);
}
@@ -238,8 +233,7 @@ TEST_F(CardUnmaskPromptControllerImplTest, LogUnmaskedCardFirstAttempt) {
TEST_F(CardUnmaskPromptControllerImplTest, LogUnmaskedCardAfterFailure) {
ShowPromptAndSimulateResponse(false);
controller_->OnVerificationResult(AutofillClient::TRY_AGAIN_FAILURE);
- controller_->OnUnmaskResponse(ASCIIToUTF16("444"),
- ASCIIToUTF16("01"),
+ controller_->OnUnmaskResponse(ASCIIToUTF16("444"), ASCIIToUTF16("01"),
ASCIIToUTF16("2050"),
false /* should_store_pan */);
base::HistogramTester histogram_tester;
diff --git a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_view.h b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_view.h
index a234739f1c5..d0970ccf55e 100644
--- a/chromium/components/autofill/core/browser/ui/card_unmask_prompt_view.h
+++ b/chromium/components/autofill/core/browser/ui/payments/card_unmask_prompt_view.h
@@ -2,8 +2,8 @@
// 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_UNMASK_PROMPT_VIEW_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_UNMASK_PROMPT_VIEW_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_VIEW_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_VIEW_H_
#include "base/macros.h"
#include "base/strings/string16.h"
@@ -31,4 +31,4 @@ class CardUnmaskPromptView {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_CARD_UNMASK_PROMPT_VIEW_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_CARD_UNMASK_PROMPT_VIEW_H_
diff --git a/chromium/components/autofill/core/browser/ui/local_card_migration_bubble_controller.h b/chromium/components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h
index f28eac96a70..ff23e775412 100644
--- a/chromium/components/autofill/core/browser/ui/local_card_migration_bubble_controller.h
+++ b/chromium/components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h
@@ -2,8 +2,8 @@
// 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_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_
#include "base/macros.h"
#include "base/strings/string16.h"
@@ -30,4 +30,4 @@ class LocalCardMigrationBubbleController {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_
diff --git a/chromium/components/autofill/core/browser/ui/local_card_migration_dialog_controller.h b/chromium/components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h
index f2dcc17dd9c..915edea65a2 100644
--- a/chromium/components/autofill/core/browser/ui/local_card_migration_dialog_controller.h
+++ b/chromium/components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h
@@ -2,15 +2,15 @@
// 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_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_
#include <memory>
#include <vector>
#include "base/macros.h"
#include "base/strings/string16.h"
-#include "components/autofill/core/browser/legal_message_line.h"
+#include "components/autofill/core/browser/payments/legal_message_line.h"
#include "url/gurl.h"
namespace autofill {
@@ -46,4 +46,4 @@ class LocalCardMigrationDialogController {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_
diff --git a/chromium/components/autofill/core/browser/ui/save_card_bubble_controller.h b/chromium/components/autofill/core/browser/ui/payments/save_card_bubble_controller.h
index d549f559552..04ba8d4bb9e 100644
--- a/chromium/components/autofill/core/browser/ui/save_card_bubble_controller.h
+++ b/chromium/components/autofill/core/browser/ui/payments/save_card_bubble_controller.h
@@ -2,8 +2,8 @@
// 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_SAVE_CARD_BUBBLE_CONTROLLER_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_SAVE_CARD_BUBBLE_CONTROLLER_H_
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_SAVE_CARD_BUBBLE_CONTROLLER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_SAVE_CARD_BUBBLE_CONTROLLER_H_
#include <memory>
#include <vector>
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "components/autofill/core/browser/autofill_client.h"
-#include "components/autofill/core/browser/legal_message_line.h"
+#include "components/autofill/core/browser/payments/legal_message_line.h"
#include "components/autofill/core/browser/sync_utils.h"
#include "components/signin/core/browser/account_info.h"
#include "url/gurl.h"
@@ -98,4 +98,4 @@ class SaveCardBubbleController {
} // namespace autofill
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_SAVE_CARD_BUBBLE_CONTROLLER_H_
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_SAVE_CARD_BUBBLE_CONTROLLER_H_
diff --git a/chromium/components/autofill/core/browser/webdata/OWNERS b/chromium/components/autofill/core/browser/webdata/OWNERS
index edcc64dbae7..0953786ed87 100644
--- a/chromium/components/autofill/core/browser/webdata/OWNERS
+++ b/chromium/components/autofill/core/browser/webdata/OWNERS
@@ -1,2 +1,8 @@
per-file *sync_bridge*=jkrcal@chromium.org
per-file *sync_bridge*=file://components/sync/OWNERS
+
+per-file *syncable_service*=jkrcal@chromium.org
+per-file *syncable_service*=file://components/sync/OWNERS
+
+per-file *type_controller*=jkrcal@chromium.org
+per-file *type_controller*=file://components/sync/OWNERS
diff --git a/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc b/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
index 1eebf032d16..d8b1239f701 100644
--- a/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
+++ b/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.cc
@@ -330,9 +330,9 @@ Optional<syncer::ModelError> AutocompleteSyncBridge::MergeSyncData(
SyncDifferenceTracker tracker(GetAutofillTable());
for (const auto& change : entity_data) {
- DCHECK(change.data().specifics.has_autofill());
+ DCHECK(change->data().specifics.has_autofill());
RETURN_IF_ERROR(tracker.IncorporateRemoteSpecifics(
- change.storage_key(), change.data().specifics.autofill()));
+ change->storage_key(), change->data().specifics.autofill()));
}
RETURN_IF_ERROR(tracker.FlushToLocal(web_data_backend_));
@@ -346,6 +346,7 @@ Optional<syncer::ModelError> AutocompleteSyncBridge::MergeSyncData(
web_data_backend_->RemoveExpiredFormElements();
}
+ web_data_backend_->CommitChanges();
web_data_backend_->NotifyThatSyncHasStarted(syncer::AUTOFILL);
return {};
}
@@ -356,13 +357,13 @@ Optional<ModelError> AutocompleteSyncBridge::ApplySyncChanges(
DCHECK(thread_checker_.CalledOnValidThread());
SyncDifferenceTracker tracker(GetAutofillTable());
- for (const EntityChange& change : entity_changes) {
- if (change.type() == EntityChange::ACTION_DELETE) {
- RETURN_IF_ERROR(tracker.IncorporateRemoteDelete(change.storage_key()));
+ for (const std::unique_ptr<EntityChange>& change : entity_changes) {
+ if (change->type() == EntityChange::ACTION_DELETE) {
+ RETURN_IF_ERROR(tracker.IncorporateRemoteDelete(change->storage_key()));
} else {
- DCHECK(change.data().specifics.has_autofill());
+ DCHECK(change->data().specifics.has_autofill());
RETURN_IF_ERROR(tracker.IncorporateRemoteSpecifics(
- change.storage_key(), change.data().specifics.autofill()));
+ change->storage_key(), change->data().specifics.autofill()));
}
}
@@ -376,6 +377,8 @@ Optional<ModelError> AutocompleteSyncBridge::ApplySyncChanges(
autofill::features::kAutocompleteRetentionPolicyEnabled)) {
web_data_backend_->RemoveExpiredFormElements();
}
+
+ web_data_backend_->CommitChanges();
return {};
}
@@ -470,6 +473,11 @@ void AutocompleteSyncBridge::ActOnLocalChanges(
}
}
+ // We do not need to commit any local changes (written by the processor via
+ // the metadata change list) because the open WebDatabase transaction is
+ // committed by the AutofillWebDataService when the original local write
+ // operation (that triggered this notification to the bridge) finishes.
+
if (Optional<ModelError> error = metadata_change_list->TakeError())
change_processor()->ReportError(*error);
}
diff --git a/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h b/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h
index a36fce9f138..78f71ad157f 100644
--- a/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h
+++ b/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge.h
@@ -12,6 +12,7 @@
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "base/supports_user_data.h"
+#include "base/threading/thread_checker.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
#include "components/sync/model/metadata_change_list.h"
diff --git a/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc b/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
index d7dfa2eff27..4547ed5acca 100644
--- a/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
@@ -49,7 +49,6 @@ using syncer::DataBatch;
using syncer::EntityChange;
using syncer::EntityChangeList;
using syncer::EntityData;
-using syncer::EntityDataPtr;
using syncer::HasInitialSyncDone;
using syncer::IsEmptyMetadataBatch;
using syncer::KeyAndData;
@@ -186,7 +185,7 @@ class AutocompleteSyncBridgeTest : public testing::Test {
for (const AutofillSpecifics& specifics : remote_data) {
initial_updates.push_back(SpecificsToUpdateResponse(specifics));
}
- real_processor_->OnUpdateReceived(state, initial_updates);
+ real_processor_->OnUpdateReceived(state, std::move(initial_updates));
}
void SaveSpecificsToTable(
@@ -223,15 +222,13 @@ class AutocompleteSyncBridgeTest : public testing::Test {
}
std::string GetClientTag(const AutofillSpecifics& specifics) {
- std::string tag =
- bridge()->GetClientTag(SpecificsToEntity(specifics).value());
+ std::string tag = bridge()->GetClientTag(*SpecificsToEntity(specifics));
EXPECT_FALSE(tag.empty());
return tag;
}
std::string GetStorageKey(const AutofillSpecifics& specifics) {
- std::string key =
- bridge()->GetStorageKey(SpecificsToEntity(specifics).value());
+ std::string key = bridge()->GetStorageKey(*SpecificsToEntity(specifics));
EXPECT_FALSE(key.empty());
return key;
}
@@ -246,24 +243,25 @@ class AutocompleteSyncBridgeTest : public testing::Test {
return changes;
}
- EntityDataPtr SpecificsToEntity(const AutofillSpecifics& specifics) {
- EntityData data;
- *data.specifics.mutable_autofill() = specifics;
- data.client_tag_hash = syncer::GenerateSyncableHash(
- syncer::AUTOFILL, bridge()->GetClientTag(data));
- return data.PassToPtr();
+ std::unique_ptr<EntityData> SpecificsToEntity(
+ const AutofillSpecifics& specifics) {
+ auto data = std::make_unique<EntityData>();
+ *data->specifics.mutable_autofill() = specifics;
+ data->client_tag_hash = syncer::GenerateSyncableHash(
+ syncer::AUTOFILL, bridge()->GetClientTag(*data));
+ return data;
}
- syncer::UpdateResponseData SpecificsToUpdateResponse(
+ std::unique_ptr<syncer::UpdateResponseData> SpecificsToUpdateResponse(
const AutofillSpecifics& specifics) {
- syncer::UpdateResponseData data;
- data.entity = SpecificsToEntity(specifics);
+ auto data = std::make_unique<syncer::UpdateResponseData>();
+ data->entity = SpecificsToEntity(specifics);
return data;
}
- void ApplyChanges(const EntityChangeList& changes) {
+ void ApplyChanges(EntityChangeList changes) {
const auto error = bridge()->ApplySyncChanges(
- bridge()->CreateMetadataChangeList(), changes);
+ bridge()->CreateMetadataChangeList(), std::move(changes));
EXPECT_FALSE(error);
}
@@ -440,10 +438,19 @@ TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesSimple) {
ASSERT_NE(specifics1.SerializeAsString(), specifics2.SerializeAsString());
ASSERT_NE(GetStorageKey(specifics1), GetStorageKey(specifics2));
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
ApplyAdds({specifics1, specifics2});
VerifyAllData({specifics1, specifics2});
- ApplyChanges({EntityChange::CreateDelete(GetStorageKey(specifics1))});
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
+ syncer::EntityChangeList entity_change_list;
+ entity_change_list.push_back(
+ EntityChange::CreateDelete(GetStorageKey(specifics1)));
+ ApplyChanges(std::move(entity_change_list));
VerifyAllData({specifics2});
}
@@ -479,13 +486,24 @@ TEST_F(AutocompleteSyncBridgeTest,
// existing ones.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesWrongChangeType) {
AutofillSpecifics specifics = CreateSpecifics(1, {1});
- ApplyChanges({EntityChange::CreateDelete(GetStorageKey(specifics))});
+ syncer::EntityChangeList entity_change_list1;
+ entity_change_list1.push_back(
+ EntityChange::CreateDelete(GetStorageKey(specifics)));
+ ApplyChanges(std::move(entity_change_list1));
VerifyAllData(std::vector<AutofillSpecifics>());
- ApplyChanges({EntityChange::CreateUpdate(GetStorageKey(specifics),
- SpecificsToEntity(specifics))});
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
+ syncer::EntityChangeList entity_change_list2;
+ entity_change_list2.push_back(EntityChange::CreateUpdate(
+ GetStorageKey(specifics), SpecificsToEntity(specifics)));
+ ApplyChanges(std::move(entity_change_list2));
VerifyAllData({specifics});
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
specifics.add_usage_timestamp(Time::FromTimeT(2).ToInternalValue());
ApplyAdds({specifics});
VerifyAllData({specifics});
@@ -564,9 +582,10 @@ TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesMinMaxTimestamps) {
// should never happen in practice because storage keys should be generated at
// runtime by the bridge and not loaded from disk.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesBadStorageKey) {
+ syncer::EntityChangeList entity_change_list;
+ entity_change_list.push_back(EntityChange::CreateDelete("bogus storage key"));
const auto error = bridge()->ApplySyncChanges(
- bridge()->CreateMetadataChangeList(),
- {EntityChange::CreateDelete("bogus storage key")});
+ bridge()->CreateMetadataChangeList(), std::move(entity_change_list));
EXPECT_TRUE(error);
}
@@ -587,6 +606,11 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntriesAdded) {
EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(added_specifics1), _));
EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(added_specifics2), _));
+ // Bridge should not commit transaction on local changes (it is committed by
+ // the AutofillWebDataService itself).
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+
bridge()->AutofillEntriesChanged(
{AutofillChange(AutofillChange::ADD, added_entry1.key()),
AutofillChange(AutofillChange::ADD, added_entry2.key())});
@@ -598,6 +622,10 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntryAddedThenUpdated) {
const AutofillEntry added_entry = CreateAutofillEntry(added_specifics);
table()->UpdateAutofillEntries({added_entry});
EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(added_specifics), _));
+ // Bridge should not commit transaction on local changes (it is committed by
+ // the AutofillWebDataService itself).
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillEntriesChanged(
{AutofillChange(AutofillChange::ADD, added_entry.key())});
@@ -606,6 +634,10 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntryAddedThenUpdated) {
const AutofillEntry updated_entry = CreateAutofillEntry(updated_specifics);
table()->UpdateAutofillEntries({updated_entry});
EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(updated_specifics), _));
+ // Bridge should not commit transaction on local changes (it is committed by
+ // the AutofillWebDataService itself).
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillEntriesChanged(
{AutofillChange(AutofillChange::UPDATE, updated_entry.key())});
@@ -618,6 +650,11 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntryDeleted) {
const std::string storage_key = GetStorageKey(deleted_specifics);
EXPECT_CALL(mock_processor(), Delete(storage_key, _));
+ // Bridge should not commit transaction on local changes (it is committed by
+ // the AutofillWebDataService itself).
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+
bridge()->AutofillEntriesChanged(
{AutofillChange(AutofillChange::REMOVE, deleted_entry.key())});
}
@@ -640,6 +677,10 @@ TEST_F(AutocompleteSyncBridgeTest, LocalEntryExpired) {
ASSERT_EQ(1U, batch.TakeAllMetadata().size());
EXPECT_CALL(mock_processor(), UntrackEntityForStorageKey(storage_key));
+ // Bridge should not commit transaction on local changes (it is committed by
+ // the AutofillWebDataService itself).
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillEntriesChanged(
{AutofillChange(AutofillChange::EXPIRE, expired_entry.key())});
@@ -673,6 +714,9 @@ TEST_F(AutocompleteSyncBridgeTest, LoadMetadataReportsErrorForMissingDB) {
TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataEmpty) {
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // The bridge should still commit the model type state change.
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing(/*remote_data=*/std::vector<AutofillSpecifics>());
@@ -685,6 +729,8 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataRemoteOnly) {
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
StartSyncing(/*remote_data=*/{specifics1, specifics2});
@@ -702,6 +748,9 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataLocalOnly) {
ApplyAdds({specifics1, specifics2});
VerifyAllData({specifics1, specifics2});
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+
StartSyncing(/*remote_data=*/{});
VerifyAllData({specifics1, specifics2});
}
@@ -734,6 +783,9 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataAllMerged) {
ApplyAdds({local1, local2, local3, local4, local5, local6});
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
StartSyncing(
/*remote_data=*/{remote1, remote2, remote3, remote4, remote5, remote6});
VerifyAllData({merged1, merged2, merged3, merged4, merged5, merged6});
@@ -753,6 +805,9 @@ TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataMixed) {
ApplyAdds({local1, specifics3, local4});
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
StartSyncing(/*remote_data=*/{remote2, specifics3, remote4});
VerifyAllData({local1, remote2, specifics3, merged4});
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_change.h b/chromium/components/autofill/core/browser/webdata/autofill_change.h
index 9605de1e35b..f23695ad741 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_change.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_change.h
@@ -55,16 +55,12 @@ class AutofillDataModelChange : public GenericAutofillChange<std::string> {
// The |type| input specifies the change type. The |key| input is the key
// that identifies the |data_model|; it is the GUID of the entry for local
// data and server_id of the entry for server data from GPay.
- // When |type| == ADD, |data_model| should be non-NULL.
- // When |type| == UPDATE, |data_model| should be non-NULL.
- // When |type| == REMOVE, |data_model| should be NULL.
AutofillDataModelChange(Type type,
const std::string& key,
const DataType* data_model)
: GenericAutofillChange<std::string>(type, key), data_model_(data_model) {
- DCHECK(type == REMOVE ? !data_model
- : data_model && (data_model->guid() == key ||
- data_model->server_id() == key));
+ DCHECK(data_model &&
+ (data_model->guid() == key || data_model->server_id() == key));
}
~AutofillDataModelChange() override {}
@@ -90,11 +86,6 @@ class AutofillProfileDeepChange : public AutofillProfileChange {
: AutofillProfileChange(type, profile.guid(), &profile),
profile_(profile) {}
- AutofillProfileDeepChange(Type type, const std::string& guid)
- : AutofillProfileChange(type, guid, nullptr), profile_(guid, "") {
- DCHECK(type == GenericAutofillChange::REMOVE);
- }
-
~AutofillProfileDeepChange() override {}
const AutofillProfile* profile() const { return &profile_; }
@@ -106,8 +97,8 @@ class AutofillProfileDeepChange : public AutofillProfileChange {
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_; }
+ void set_enforced() { enforced_ = true; }
+ bool enforced() const { return enforced_; }
private:
AutofillProfile profile_;
@@ -121,9 +112,9 @@ class AutofillProfileDeepChange : public AutofillProfileChange {
// 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;
+ // Is true when the change should happen regardless of an existing or equal
+ // profile.
+ mutable bool enforced_ = 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 bd2bff78a16..aff933bf806 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
@@ -14,7 +14,6 @@
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_service.h"
-#include "components/sync/base/experiments.h"
#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/sync_error.h"
@@ -23,7 +22,7 @@
namespace browser_sync {
AutofillProfileDataTypeController::AutofillProfileDataTypeController(
- scoped_refptr<base::SingleThreadTaskRunner> db_thread,
+ scoped_refptr<base::SequencedTaskRunner> db_thread,
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
@@ -76,10 +75,9 @@ bool AutofillProfileDataTypeController::StartModels() {
DCHECK(CalledOnValidThread());
DCHECK_EQ(state(), MODEL_STARTING);
- if (!IsEnabled()) {
- DisableForPolicy();
+ if (!IsEnabled())
return false;
- }
+
autofill::PersonalDataManager* personal_data = pdm_provider_.Run();
// Make sure PDM has the sync service. This is needed because in the account
@@ -135,13 +133,7 @@ void AutofillProfileDataTypeController::OnUserPrefChanged() {
return; // No change to sync state.
currently_enabled_ = new_enabled;
- if (currently_enabled_) {
- // The preference was just enabled. Trigger a reconfiguration. This will do
- // nothing if the type isn't preferred.
- sync_service()->ReenableDatatype(type());
- } else {
- DisableForPolicy();
- }
+ sync_service()->ReadyForStartChanged(type());
}
bool AutofillProfileDataTypeController::IsEnabled() {
@@ -152,12 +144,4 @@ bool AutofillProfileDataTypeController::IsEnabled() {
sync_client()->GetPrefService());
}
-void AutofillProfileDataTypeController::DisableForPolicy() {
- if (state() != NOT_RUNNING && state() != STOPPING) {
- CreateErrorHandler()->OnUnrecoverableError(
- syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_POLICY_ERROR,
- "Profile syncing is disabled by policy.", type()));
- }
-}
-
} // namespace browser_sync
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 4641b0d223d..f755ca28659 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
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/scoped_observer.h"
-#include "base/single_thread_task_runner.h"
+#include "base/sequenced_task_runner.h"
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync/driver/async_directory_type_controller.h"
@@ -37,7 +37,7 @@ class AutofillProfileDataTypeController
// |dump_stack| is called when an unrecoverable error occurs.
AutofillProfileDataTypeController(
- scoped_refptr<base::SingleThreadTaskRunner> db_thread,
+ scoped_refptr<base::SequencedTaskRunner> db_thread,
const base::Closure& dump_stack,
syncer::SyncService* sync_service,
syncer::SyncClient* sync_client,
@@ -64,9 +64,6 @@ class AutofillProfileDataTypeController
// Returns true if the pref is set such that autofill sync should be enabled.
bool IsEnabled();
- // Report an error (which will stop the datatype asynchronously).
- void DisableForPolicy();
-
// Callback that allows accessing PersonalDataManager lazily.
const PersonalDataManagerProvider pdm_provider_;
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 a5047b4ae5b..0e91e96b37f 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
@@ -108,14 +108,15 @@ Optional<syncer::ModelError> AutofillProfileSyncBridge::MergeSyncData(
GetAutofillTable());
for (const auto& change : entity_data) {
- DCHECK(change.data().specifics.has_autofill_profile());
+ DCHECK(change->data().specifics.has_autofill_profile());
std::unique_ptr<AutofillProfile> remote =
CreateAutofillProfileFromSpecifics(
- change.data().specifics.autofill_profile());
+ change->data().specifics.autofill_profile());
if (!remote) {
- DVLOG(2) << "[AUTOFILL SYNC] Invalid remote specifics "
- << change.data().specifics.autofill_profile().SerializeAsString()
- << " received from the server in an initial sync.";
+ DVLOG(2)
+ << "[AUTOFILL SYNC] Invalid remote specifics "
+ << change->data().specifics.autofill_profile().SerializeAsString()
+ << " received from the server in an initial sync.";
continue;
}
RETURN_IF_ERROR(
@@ -128,6 +129,7 @@ Optional<syncer::ModelError> AutofillProfileSyncBridge::MergeSyncData(
&initial_sync_tracker,
AutofillProfileSyncChangeOrigin::kInitial));
+ web_data_backend_->CommitChanges();
web_data_backend_->NotifyThatSyncHasStarted(syncer::AUTOFILL_PROFILE);
return base::nullopt;
}
@@ -138,18 +140,18 @@ Optional<ModelError> AutofillProfileSyncBridge::ApplySyncChanges(
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
AutofillProfileSyncDifferenceTracker tracker(GetAutofillTable());
- for (const syncer::EntityChange& change : entity_changes) {
- if (change.type() == syncer::EntityChange::ACTION_DELETE) {
- RETURN_IF_ERROR(tracker.IncorporateRemoteDelete(change.storage_key()));
+ for (const std::unique_ptr<syncer::EntityChange>& change : entity_changes) {
+ if (change->type() == syncer::EntityChange::ACTION_DELETE) {
+ RETURN_IF_ERROR(tracker.IncorporateRemoteDelete(change->storage_key()));
} else {
- DCHECK(change.data().specifics.has_autofill_profile());
+ DCHECK(change->data().specifics.has_autofill_profile());
std::unique_ptr<AutofillProfile> remote =
CreateAutofillProfileFromSpecifics(
- change.data().specifics.autofill_profile());
+ change->data().specifics.autofill_profile());
if (!remote) {
DVLOG(2)
<< "[AUTOFILL SYNC] Invalid remote specifics "
- << change.data().specifics.autofill_profile().SerializeAsString()
+ << change->data().specifics.autofill_profile().SerializeAsString()
<< " received from the server in an initial sync.";
continue;
}
@@ -157,8 +159,12 @@ Optional<ModelError> AutofillProfileSyncBridge::ApplySyncChanges(
}
}
- return FlushSyncTracker(std::move(metadata_change_list), &tracker,
- AutofillProfileSyncChangeOrigin::kIncrementalRemote);
+ RETURN_IF_ERROR(
+ FlushSyncTracker(std::move(metadata_change_list), &tracker,
+ AutofillProfileSyncChangeOrigin::kIncrementalRemote));
+
+ web_data_backend_->CommitChanges();
+ return base::nullopt;
}
void AutofillProfileSyncBridge::GetData(StorageKeyList storage_keys,
@@ -203,12 +209,8 @@ void AutofillProfileSyncBridge::GetAllDataForDebugging(DataCallback callback) {
void AutofillProfileSyncBridge::ActOnLocalChange(
const AutofillProfileChange& change) {
- DCHECK((change.type() == AutofillProfileChange::REMOVE) ==
- (change.data_model() == nullptr));
- if (!change_processor()->IsTrackingMetadata()) {
- return;
- }
- if (change.data_model() &&
+ DCHECK(change.data_model());
+ if (!change_processor()->IsTrackingMetadata() ||
change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
return;
}
@@ -218,19 +220,10 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
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_);
- }
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+ GetAutofillTable()->GetServerProfiles(&server_profiles);
+ bool is_converted_from_server = IsLocalProfileEqualToServerProfile(
+ server_profiles, *change.data_model(), app_locale_);
switch (change.type()) {
case AutofillProfileChange::ADD:
@@ -247,12 +240,6 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
: AutofillProfileSyncChangeOrigin::kTrulyLocal);
break;
case AutofillProfileChange::REMOVE:
- // Removals have no data_model() so this change can still be for a
- // SERVER_PROFILE. We have no simple way to rule it out. For the time
- // being we rely on the processor ignoring deletions for storage keys it
- // does not know.
- // 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.
@@ -267,6 +254,11 @@ void AutofillProfileSyncBridge::ActOnLocalChange(
break;
}
+ // We do not need to commit any local changes (written by the processor via
+ // the metadata change list) because the open WebDatabase transaction is
+ // committed by the AutofillWebDataService when the original local write
+ // operation (that triggered this notification to the bridge) finishes.
+
if (Optional<ModelError> error = metadata_change_list->TakeError()) {
change_processor()->ReportError(*error);
}
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 08e50b60dfa..4b1986b1a61 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
@@ -53,7 +53,6 @@ using syncer::DataBatch;
using syncer::EntityChange;
using syncer::EntityChangeList;
using syncer::EntityData;
-using syncer::EntityDataPtr;
using syncer::KeyAndData;
using syncer::MockModelTypeChangeProcessor;
using syncer::ModelType;
@@ -264,12 +263,12 @@ class AutofillProfileSyncBridgeTest : public testing::Test {
for (const AutofillProfileSpecifics& specifics : remote_data) {
initial_updates.push_back(SpecificsToUpdateResponse(specifics));
}
- real_processor_->OnUpdateReceived(state, initial_updates);
+ real_processor_->OnUpdateReceived(state, std::move(initial_updates));
}
- void ApplySyncChanges(const EntityChangeList& changes) {
+ void ApplySyncChanges(EntityChangeList changes) {
const base::Optional<syncer::ModelError> error = bridge()->ApplySyncChanges(
- bridge()->CreateMetadataChangeList(), changes);
+ bridge()->CreateMetadataChangeList(), std::move(changes));
EXPECT_FALSE(error) << error->ToString();
}
@@ -293,18 +292,19 @@ class AutofillProfileSyncBridgeTest : public testing::Test {
return data;
}
- EntityDataPtr SpecificsToEntity(const AutofillProfileSpecifics& specifics) {
- EntityData data;
- *data.specifics.mutable_autofill_profile() = specifics;
- data.client_tag_hash = syncer::GenerateSyncableHash(
- syncer::AUTOFILL_PROFILE, bridge()->GetClientTag(data));
- return data.PassToPtr();
+ std::unique_ptr<EntityData> SpecificsToEntity(
+ const AutofillProfileSpecifics& specifics) {
+ auto data = std::make_unique<EntityData>();
+ *data->specifics.mutable_autofill_profile() = specifics;
+ data->client_tag_hash = syncer::GenerateSyncableHash(
+ syncer::AUTOFILL_PROFILE, bridge()->GetClientTag(*data));
+ return data;
}
- syncer::UpdateResponseData SpecificsToUpdateResponse(
+ std::unique_ptr<syncer::UpdateResponseData> SpecificsToUpdateResponse(
const AutofillProfileSpecifics& specifics) {
- syncer::UpdateResponseData data;
- data.entity = SpecificsToEntity(specifics);
+ auto data = std::make_unique<syncer::UpdateResponseData>();
+ data->entity = SpecificsToEntity(specifics);
return data;
}
@@ -342,6 +342,9 @@ TEST_F(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Added) {
EXPECT_CALL(
mock_processor(),
Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
+ // The bridge does not need to commit when reacting to a notification about a
+ // local change.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
bridge()->AutofillProfileChanged(change);
}
@@ -358,6 +361,9 @@ TEST_F(AutofillProfileSyncBridgeTest,
EXPECT_CALL(
mock_processor(),
Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
+ // The bridge does not need to commit when reacting to a notification about a
+ // local change.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
bridge()->AutofillProfileChanged(change);
}
@@ -374,6 +380,9 @@ TEST_F(AutofillProfileSyncBridgeTest,
EXPECT_CALL(
mock_processor(),
Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
+ // The bridge does not need to commit when reacting to a notification about a
+ // local change.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
bridge()->AutofillProfileChanged(change);
}
@@ -389,6 +398,9 @@ TEST_F(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Updated) {
EXPECT_CALL(
mock_processor(),
Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
+ // The bridge does not need to commit when reacting to a notification about a
+ // local change.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
bridge()->AutofillProfileChanged(change);
}
@@ -417,6 +429,9 @@ TEST_F(AutofillProfileSyncBridgeTest,
EXPECT_CALL(
mock_processor(),
Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
+ // The bridge does not need to commit when reacting to a notification about a
+ // local change.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
bridge()->AutofillProfileChanged(change);
}
@@ -438,12 +453,31 @@ TEST_F(AutofillProfileSyncBridgeTest,
TEST_F(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Deleted) {
StartSyncing({});
- AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuidB, nullptr);
+ AutofillProfile local(kGuidB, kHttpsOrigin);
+ local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
+ AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuidB, &local);
EXPECT_CALL(mock_processor(), Delete(kGuidB, _));
+ // The bridge does not need to commit when reacting to a notification about a
+ // local change.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
bridge()->AutofillProfileChanged(change);
}
+// Server profile updates should be ignored.
+TEST_F(AutofillProfileSyncBridgeTest,
+ AutofillProfileChanged_Deleted_IgnoreServerProfiles) {
+ StartSyncing({});
+
+ AutofillProfile server_profile(AutofillProfile::SERVER_PROFILE, "server-id");
+ AutofillProfileChange change(AutofillProfileChange::REMOVE,
+ server_profile.guid(), &server_profile);
+
+ EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ // Should not crash.
+ bridge()->AutofillProfileChanged(change);
+}
+
TEST_F(AutofillProfileSyncBridgeTest, GetAllDataForDebugging) {
AutofillProfile local1 = AutofillProfile(kGuidA, kHttpsOrigin);
local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
@@ -503,6 +537,7 @@ TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData) {
mock_processor(),
Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local1)), _));
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote1, remote2, remote3});
@@ -521,6 +556,8 @@ TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_SyncAllFieldsToServer) {
// This complete profile is fully uploaded to sync.
EXPECT_CALL(mock_processor(),
Put(_, HasSpecifics(ConstructCompleteSpecifics()), _));
+ EXPECT_CALL(*backend(), CommitChanges());
+
StartSyncing({});
// No changes locally.
@@ -531,6 +568,7 @@ TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_SyncAllFieldsToServer) {
// the client (and nothing gets uploaded back).
TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_SyncAllFieldsToClient) {
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({ConstructCompleteSpecifics()});
EXPECT_THAT(GetAllLocalData(),
@@ -562,6 +600,7 @@ TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_IdenticalProfiles) {
AutofillProfileSpecifics merged2(remote2);
merged2.set_origin(kSettingsOrigin);
EXPECT_CALL(mock_processor(), Put(kGuidD, HasSpecifics(merged2), _));
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote1, remote2});
@@ -595,6 +634,7 @@ TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_NonSimilarProfiles) {
mock_processor(),
Put(kGuidA, HasSpecifics(CreateAutofillProfileSpecifics(local)), _));
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
@@ -646,6 +686,7 @@ TEST_F(AutofillProfileSyncBridgeTest, MergeSyncData_SimilarProfiles) {
mock_processor(),
Put(kGuidB, HasSpecifics(CreateAutofillProfileSpecifics(local2)), _));
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote1, remote2});
@@ -680,6 +721,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
merged.set_use_date(30);
merged.add_phone_home_whole_number("650234567");
EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
}
@@ -703,6 +745,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
AutofillProfileSpecifics merged(remote);
merged.add_phone_home_whole_number("650234567");
EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
}
@@ -726,6 +769,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
merged.set_use_count(12);
merged.add_phone_home_whole_number("650234567");
EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
}
@@ -751,6 +795,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// explicitly covered by previous tests but happens.
merged.set_address_home_language_code("");
EXPECT_CALL(mock_processor(), Put(kGuidB, HasSpecifics(merged), _));
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
}
@@ -770,6 +815,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// Expect no sync events to add origin to the remote data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
// Expect the local autofill profile to still have an origin after sync.
@@ -795,6 +841,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
ASSERT_FALSE(remote.has_origin());
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
@@ -811,10 +858,13 @@ TEST_F(AutofillProfileSyncBridgeTest, ApplySyncChanges) {
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
- ApplySyncChanges(
- {EntityChange::CreateDelete(kGuidA),
- EntityChange::CreateAdd(kGuidB, SpecificsToEntity(remote))});
+ syncer::EntityChangeList entity_change_list;
+ entity_change_list.push_back(EntityChange::CreateDelete(kGuidA));
+ entity_change_list.push_back(
+ EntityChange::CreateAdd(kGuidB, SpecificsToEntity(remote)));
+ ApplySyncChanges(std::move(entity_change_list));
EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
}
@@ -829,10 +879,14 @@ TEST_F(AutofillProfileSyncBridgeTest, ApplySyncChanges_OmitsInvalidSpecifics) {
CreateAutofillProfileSpecifics(kGuidInvalid, std::string());
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
- ApplySyncChanges(
- {EntityChange::CreateAdd(kGuidA, SpecificsToEntity(remote_valid)),
- EntityChange::CreateAdd(kGuidInvalid,
- SpecificsToEntity(remote_invalid))});
+ EXPECT_CALL(*backend(), CommitChanges());
+
+ syncer::EntityChangeList entity_change_list;
+ entity_change_list.push_back(
+ EntityChange::CreateAdd(kGuidA, SpecificsToEntity(remote_valid)));
+ entity_change_list.push_back(
+ EntityChange::CreateAdd(kGuidInvalid, SpecificsToEntity(remote_invalid)));
+ ApplySyncChanges(std::move(entity_change_list));
EXPECT_THAT(GetAllLocalData(),
ElementsAre(CreateAutofillProfile(remote_valid)));
@@ -888,6 +942,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
remote.set_address_home_street_address(
"456 El Camino Real\n"
"Suite #1337");
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
@@ -922,6 +977,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, no change in local data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
@@ -940,6 +996,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, no change in local data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
@@ -958,6 +1015,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, remote language code overwrites the empty local one.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
}
@@ -976,6 +1034,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, remote language code overwrites the local one.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
}
@@ -1001,6 +1060,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, remote language code overwrites the local one.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
@@ -1021,6 +1081,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, no change in local data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
@@ -1040,6 +1101,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, the validity bitfield should be stored to local.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
}
@@ -1059,6 +1121,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, the remote validity bitfield should overwrite local.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(CreateAutofillProfile(remote)));
}
@@ -1083,6 +1146,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, the local validity bitfield should stay untouched.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
@@ -1102,6 +1166,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, no change in local data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
@@ -1128,6 +1193,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, no change in local data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
@@ -1151,6 +1217,7 @@ TEST_F(AutofillProfileSyncBridgeTest,
// No update to sync, no change in local data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(WithUsageStats(local)));
}
@@ -1203,6 +1270,7 @@ TEST_P(AutofillProfileSyncBridgeUpdatesUsageStatsTest, UpdatesUsageStats) {
// Expect no changes to remote data.
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
StartSyncing({remote});
EXPECT_THAT(GetAllLocalData(), ElementsAre(WithUsageStats(merged)));
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 8022c6abd15..1a6b46119b3 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
@@ -94,6 +94,12 @@ AutofillProfileSyncableService::FromWebDataService(
AutofillProfileSyncableService::AutofillProfileSyncableService()
: webdata_backend_(nullptr), scoped_observer_(this) {}
+void AutofillProfileSyncableService::WaitUntilReadyToSync(
+ base::OnceClosure done) {
+ // Not used in the legacy directory-based architecture.
+ NOTREACHED();
+}
+
syncer::SyncMergeResult
AutofillProfileSyncableService::MergeDataAndStartSyncing(
syncer::ModelType type,
@@ -602,33 +608,21 @@ AutofillProfileSyncableService::CreateOrUpdateProfile(
void AutofillProfileSyncableService::ActOnChange(
const AutofillProfileChange& change) {
- DCHECK(
- (change.type() == AutofillProfileChange::REMOVE &&
- !change.data_model()) ||
- (change.type() != AutofillProfileChange::REMOVE && change.data_model()));
+ DCHECK(change.data_model());
DCHECK(sync_processor_);
- if (change.data_model() &&
- change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
+ if (change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
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_);
- }
+ // |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;
@@ -668,13 +662,10 @@ void AutofillProfileSyncableService::ActOnChange(
break;
}
case AutofillProfileChange::REMOVE: {
- // Removals have no data_model() so this change can still be for a
- // SERVER_PROFILE. Rule it out by a lookup in profiles_map_.
if (profiles_map_.find(change.key()) != profiles_map_.end()) {
- AutofillProfile empty_profile(change.key(), std::string());
new_changes.push_back(
syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE,
- CreateData(empty_profile)));
+ CreateData(*(change.data_model()))));
profiles_map_.erase(change.key());
// TODO(crbug.com/904390): Remove when the investigation is over.
ReportAutofillProfileDeleteOrigin(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.h b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.h
index 079ff91ee41..d9638107dbc 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_profile_syncable_service.h
@@ -70,6 +70,7 @@ class AutofillProfileSyncableService
static syncer::ModelType model_type() { return syncer::AUTOFILL_PROFILE; }
// syncer::SyncableService implementation.
+ void WaitUntilReadyToSync(base::OnceClosure done) override;
syncer::SyncMergeResult MergeDataAndStartSyncing(
syncer::ModelType type,
const syncer::SyncDataList& initial_sync_data,
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 1b605e9446b..6291ce17df9 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
@@ -593,7 +593,8 @@ TEST_F(AutofillProfileSyncableServiceTest, AutofillProfileDeleted) {
AutofillProfileChange change1(AutofillProfileChange::ADD, kGuid1, &profile);
autofill_syncable_service_.AutofillProfileChanged(change1);
- AutofillProfileChange change2(AutofillProfileChange::REMOVE, kGuid1, nullptr);
+ AutofillProfileChange change2(AutofillProfileChange::REMOVE, kGuid1,
+ &profile);
autofill_syncable_service_.AutofillProfileChanged(change2);
ASSERT_EQ(1U, sync_change_processor->changes().size());
@@ -611,7 +612,9 @@ TEST_F(AutofillProfileSyncableServiceTest,
TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor;
autofill_syncable_service_.set_sync_processor(sync_change_processor);
- AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, nullptr);
+ AutofillProfile profile(kGuid2, kEmptyOrigin);
+ profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane"));
+ AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, &profile);
autofill_syncable_service_.AutofillProfileChanged(change);
ASSERT_EQ(0U, sync_change_processor->changes().size());
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc
index d0647c4bf0e..d7a591940ed 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.cc
@@ -114,45 +114,6 @@ CreditCard::CardType CardTypeFromWalletCardClass(
}
}
-// Creates an AutofillProfile from the specified |address| specifics.
-AutofillProfile ProfileFromSpecifics(
- const sync_pb::WalletPostalAddress& address) {
- AutofillProfile profile(AutofillProfile::SERVER_PROFILE, std::string());
-
- // AutofillProfile stores multi-line addresses with newline separators.
- std::vector<base::StringPiece> street_address(
- address.street_address().begin(), address.street_address().end());
- profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
- base::UTF8ToUTF16(base::JoinString(street_address, "\n")));
-
- profile.SetRawInfo(COMPANY_NAME, base::UTF8ToUTF16(address.company_name()));
- profile.SetRawInfo(ADDRESS_HOME_STATE,
- base::UTF8ToUTF16(address.address_1()));
- profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(address.address_2()));
- profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
- base::UTF8ToUTF16(address.address_3()));
- // AutofillProfile doesn't support address_4 ("sub dependent locality").
- profile.SetRawInfo(ADDRESS_HOME_ZIP,
- base::UTF8ToUTF16(address.postal_code()));
- profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE,
- base::UTF8ToUTF16(address.sorting_code()));
- profile.SetRawInfo(ADDRESS_HOME_COUNTRY,
- base::UTF8ToUTF16(address.country_code()));
- profile.set_language_code(address.language_code());
-
- // SetInfo instead of SetRawInfo so the constituent pieces will be parsed
- // for these data types.
- profile.SetInfo(NAME_FULL, base::UTF8ToUTF16(address.recipient_name()),
- profile.language_code());
- profile.SetInfo(PHONE_HOME_WHOLE_NUMBER,
- base::UTF8ToUTF16(address.phone_number()),
- profile.language_code());
-
- profile.GenerateServerProfileIdentifier();
-
- return profile;
-}
-
// Creates an AutofillProfile from the specified |card| specifics.
CreditCard CardFromSpecifics(const sync_pb::WalletMaskedCreditCard& card) {
CreditCard result(CreditCard::MASKED_SERVER_CARD, card.id());
@@ -306,6 +267,44 @@ void SetAutofillWalletSpecificsFromPaymentsCustomerData(
mutable_customer_data->set_id(customer_data.customer_id);
}
+AutofillProfile ProfileFromSpecifics(
+ const sync_pb::WalletPostalAddress& address) {
+ AutofillProfile profile(AutofillProfile::SERVER_PROFILE, std::string());
+
+ // AutofillProfile stores multi-line addresses with newline separators.
+ std::vector<base::StringPiece> street_address(
+ address.street_address().begin(), address.street_address().end());
+ profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+ base::UTF8ToUTF16(base::JoinString(street_address, "\n")));
+
+ profile.SetRawInfo(COMPANY_NAME, base::UTF8ToUTF16(address.company_name()));
+ profile.SetRawInfo(ADDRESS_HOME_STATE,
+ base::UTF8ToUTF16(address.address_1()));
+ profile.SetRawInfo(ADDRESS_HOME_CITY, base::UTF8ToUTF16(address.address_2()));
+ profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ base::UTF8ToUTF16(address.address_3()));
+ // AutofillProfile doesn't support address_4 ("sub dependent locality").
+ profile.SetRawInfo(ADDRESS_HOME_ZIP,
+ base::UTF8ToUTF16(address.postal_code()));
+ profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE,
+ base::UTF8ToUTF16(address.sorting_code()));
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY,
+ base::UTF8ToUTF16(address.country_code()));
+ profile.set_language_code(address.language_code());
+
+ // SetInfo instead of SetRawInfo so the constituent pieces will be parsed
+ // for these data types.
+ profile.SetInfo(NAME_FULL, base::UTF8ToUTF16(address.recipient_name()),
+ profile.language_code());
+ profile.SetInfo(PHONE_HOME_WHOLE_NUMBER,
+ base::UTF8ToUTF16(address.phone_number()),
+ profile.language_code());
+
+ profile.GenerateServerProfileIdentifier();
+
+ return profile;
+}
+
void CopyRelevantWalletMetadataFromDisk(
const AutofillTable& table,
std::vector<CreditCard>* cards_from_server) {
@@ -340,11 +339,11 @@ void PopulateWalletTypesFromSyncData(
std::vector<PaymentsCustomerData>* customer_data) {
std::map<std::string, std::string> ids;
- for (const syncer::EntityChange& change : entity_data) {
- DCHECK(change.data().specifics.has_autofill_wallet());
+ for (const std::unique_ptr<syncer::EntityChange>& change : entity_data) {
+ DCHECK(change->data().specifics.has_autofill_wallet());
const sync_pb::AutofillWalletSpecifics& autofill_specifics =
- change.data().specifics.autofill_wallet();
+ change->data().specifics.autofill_wallet();
switch (autofill_specifics.type()) {
case sync_pb::AutofillWalletSpecifics::MASKED_CREDIT_CARD:
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.h b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.h
index fc6812fc600..d346a679895 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util.h
@@ -48,6 +48,10 @@ void SetAutofillWalletSpecificsFromPaymentsCustomerData(
const PaymentsCustomerData& customer_data,
sync_pb::AutofillWalletSpecifics* wallet_specifics);
+// Creates an AutofillProfile from the specified |address| specifics.
+AutofillProfile ProfileFromSpecifics(
+ const sync_pb::WalletPostalAddress& address);
+
// TODO(sebsg): This should probably copy the converted state for the address
// too.
// Copies the metadata from the local cards (if present) to the corresponding
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc
index eb1f65eba3e..a76503580ee 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc
@@ -45,11 +45,12 @@ class TestAutofillTable : public AutofillTable {
DISALLOW_COPY_AND_ASSIGN(TestAutofillTable);
};
-EntityData SpecificsToEntity(const sync_pb::AutofillWalletSpecifics& specifics,
- const std::string& client_tag) {
- EntityData data;
- *data.specifics.mutable_autofill_wallet() = specifics;
- data.client_tag_hash =
+std::unique_ptr<EntityData> SpecificsToEntity(
+ const sync_pb::AutofillWalletSpecifics& specifics,
+ const std::string& client_tag) {
+ auto data = std::make_unique<syncer::EntityData>();
+ *data->specifics.mutable_autofill_wallet() = specifics;
+ data->client_tag_hash =
syncer::GenerateSyncableHash(syncer::AUTOFILL_WALLET_DATA, client_tag);
return data;
}
@@ -72,20 +73,17 @@ TEST_F(AutofillSyncBridgeUtilTest, PopulateWalletTypesFromSyncData) {
entity_data.push_back(EntityChange::CreateAdd(
address_id,
SpecificsToEntity(CreateAutofillWalletSpecificsForAddress(address_id),
- /*client_tag=*/"address-address1")
- .PassToPtr()));
+ /*client_tag=*/"address-address1")));
entity_data.push_back(EntityChange::CreateAdd(
"card1",
SpecificsToEntity(CreateAutofillWalletSpecificsForCard(
/*id=*/"card1", /*billing_address_id=*/address_id),
- /*client_tag=*/"card-card1")
- .PassToPtr()));
+ /*client_tag=*/"card-card1")));
entity_data.push_back(EntityChange::CreateAdd(
"deadbeef",
SpecificsToEntity(CreateAutofillWalletSpecificsForPaymentsCustomerData(
/*specifics_id=*/"deadbeef"),
- /*client_tag=*/"customer-deadbeef")
- .PassToPtr()));
+ /*client_tag=*/"customer-deadbeef")));
std::vector<CreditCard> wallet_cards;
std::vector<AutofillProfile> wallet_addresses;
@@ -201,4 +199,4 @@ TEST_F(AutofillSyncBridgeUtilTest,
}
} // namespace
-} // namespace autofill \ No newline at end of file
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_table.cc b/chromium/components/autofill/core/browser/webdata/autofill_table.cc
index 44741c86d84..c174b5a4785 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table.cc
@@ -1705,8 +1705,8 @@ bool AutofillTable::ClearAllLocalData() {
bool AutofillTable::RemoveAutofillDataModifiedBetween(
const base::Time& delete_begin,
const base::Time& delete_end,
- std::vector<std::string>* profile_guids,
- std::vector<std::string>* credit_card_guids) {
+ std::vector<std::unique_ptr<AutofillProfile>>* profiles,
+ std::vector<std::unique_ptr<CreditCard>>* credit_cards) {
DCHECK(delete_end.is_null() || delete_begin < delete_end);
time_t delete_begin_t = delete_begin.ToTimeT();
@@ -1719,17 +1719,20 @@ bool AutofillTable::RemoveAutofillDataModifiedBetween(
s_profiles_get.BindInt64(0, delete_begin_t);
s_profiles_get.BindInt64(1, delete_end_t);
- profile_guids->clear();
+ profiles->clear();
while (s_profiles_get.Step()) {
std::string guid = s_profiles_get.ColumnString(0);
- profile_guids->push_back(guid);
+ std::unique_ptr<AutofillProfile> profile = GetAutofillProfile(guid);
+ if (!profile)
+ return false;
+ profiles->push_back(std::move(profile));
}
if (!s_profiles_get.Succeeded())
return false;
// Remove the profile pieces.
- for (const std::string& guid : *profile_guids) {
- if (!RemoveAutofillProfilePieces(guid, db_))
+ for (const std::unique_ptr<AutofillProfile>& profile : *profiles) {
+ if (!RemoveAutofillProfilePieces(profile->guid(), db_))
return false;
}
@@ -1750,10 +1753,13 @@ bool AutofillTable::RemoveAutofillDataModifiedBetween(
s_credit_cards_get.BindInt64(0, delete_begin_t);
s_credit_cards_get.BindInt64(1, delete_end_t);
- credit_card_guids->clear();
+ credit_cards->clear();
while (s_credit_cards_get.Step()) {
std::string guid = s_credit_cards_get.ColumnString(0);
- credit_card_guids->push_back(guid);
+ std::unique_ptr<CreditCard> credit_card = GetCreditCard(guid);
+ if (!credit_card)
+ return false;
+ credit_cards->push_back(std::move(credit_card));
}
if (!s_credit_cards_get.Succeeded())
return false;
@@ -2767,9 +2773,9 @@ bool AutofillTable::GetAllSyncEntityMetadata(
while (s.Step()) {
std::string storage_key = s.ColumnString(0);
std::string serialized_metadata = s.ColumnString(1);
- sync_pb::EntityMetadata entity_metadata;
- if (entity_metadata.ParseFromString(serialized_metadata)) {
- metadata_batch->AddMetadata(storage_key, entity_metadata);
+ auto entity_metadata = std::make_unique<sync_pb::EntityMetadata>();
+ if (entity_metadata->ParseFromString(serialized_metadata)) {
+ metadata_batch->AddMetadata(storage_key, std::move(entity_metadata));
} else {
DLOG(WARNING) << "Failed to deserialize AUTOFILL model type "
"sync_pb::EntityMetadata.";
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_table.h b/chromium/components/autofill/core/browser/webdata/autofill_table.h
index ae7114f18b4..4c57a958aaf 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table.h
@@ -452,8 +452,8 @@ class AutofillTable : public WebDatabaseTable,
bool RemoveAutofillDataModifiedBetween(
const base::Time& delete_begin,
const base::Time& delete_end,
- std::vector<std::string>* profile_guids,
- std::vector<std::string>* credit_card_guids);
+ std::vector<std::unique_ptr<AutofillProfile>>* profiles,
+ std::vector<std::unique_ptr<CreditCard>>* credit_cards);
// Removes origin URLs from the autofill_profiles and credit_cards tables if
// they were written on or after |delete_begin| and strictly before
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 5ca2d3bd78a..b2f8812369a 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -1519,16 +1519,15 @@ TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) {
"VALUES('00000000-0000-0000-0000-000000000011', 67);"));
// Remove all entries modified in the bounded time range [17,41).
- std::vector<std::string> profile_guids;
- std::vector<std::string> credit_card_guids;
+ std::vector<std::unique_ptr<AutofillProfile>> profiles;
+ std::vector<std::unique_ptr<CreditCard>> credit_cards;
table_->RemoveAutofillDataModifiedBetween(
- Time::FromTimeT(17), Time::FromTimeT(41),
- &profile_guids, &credit_card_guids);
+ Time::FromTimeT(17), Time::FromTimeT(41), &profiles, &credit_cards);
// Two profiles should have been removed.
- ASSERT_EQ(2UL, profile_guids.size());
- EXPECT_EQ("00000000-0000-0000-0000-000000000001", profile_guids[0]);
- EXPECT_EQ("00000000-0000-0000-0000-000000000002", profile_guids[1]);
+ ASSERT_EQ(2UL, profiles.size());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000001", profiles[0]->guid());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000002", profiles[1]->guid());
// Make sure that only the expected profiles are still present.
sql::Statement s_autofill_profiles_bounded(
@@ -1595,10 +1594,10 @@ TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) {
EXPECT_FALSE(s_autofill_profile_phones_bounded.Step());
// Three cards should have been removed.
- ASSERT_EQ(3UL, credit_card_guids.size());
- EXPECT_EQ("00000000-0000-0000-0000-000000000006", credit_card_guids[0]);
- EXPECT_EQ("00000000-0000-0000-0000-000000000007", credit_card_guids[1]);
- EXPECT_EQ("00000000-0000-0000-0000-000000000008", credit_card_guids[2]);
+ ASSERT_EQ(3UL, credit_cards.size());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000006", credit_cards[0]->guid());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000007", credit_cards[1]->guid());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000008", credit_cards[2]->guid());
// Make sure the expected profiles are still present.
sql::Statement s_credit_cards_bounded(
@@ -1614,12 +1613,11 @@ TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) {
EXPECT_FALSE(s_credit_cards_bounded.Step());
// Remove all entries modified on or after time 51 (unbounded range).
- table_->RemoveAutofillDataModifiedBetween(
- Time::FromTimeT(51), Time(),
- &profile_guids, &credit_card_guids);
- ASSERT_EQ(2UL, profile_guids.size());
- EXPECT_EQ("00000000-0000-0000-0000-000000000004", profile_guids[0]);
- EXPECT_EQ("00000000-0000-0000-0000-000000000005", profile_guids[1]);
+ table_->RemoveAutofillDataModifiedBetween(Time::FromTimeT(51), Time(),
+ &profiles, &credit_cards);
+ ASSERT_EQ(2UL, profiles.size());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000004", profiles[0]->guid());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000005", profiles[1]->guid());
// Make sure that only the expected profile names are still present.
sql::Statement s_autofill_profiles_unbounded(
@@ -1670,9 +1668,9 @@ TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) {
EXPECT_FALSE(s_autofill_profile_phones_unbounded.Step());
// Two cards should have been removed.
- ASSERT_EQ(2UL, credit_card_guids.size());
- EXPECT_EQ("00000000-0000-0000-0000-000000000010", credit_card_guids[0]);
- EXPECT_EQ("00000000-0000-0000-0000-000000000011", credit_card_guids[1]);
+ ASSERT_EQ(2UL, credit_cards.size());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000010", credit_cards[0]->guid());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000011", credit_cards[1]->guid());
// Make sure the remaining card is the expected one.
sql::Statement s_credit_cards_unbounded(
@@ -1684,14 +1682,13 @@ TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) {
EXPECT_FALSE(s_credit_cards_unbounded.Step());
// Remove all remaining entries.
- table_->RemoveAutofillDataModifiedBetween(
- Time(), Time(),
- &profile_guids, &credit_card_guids);
+ table_->RemoveAutofillDataModifiedBetween(Time(), Time(), &profiles,
+ &credit_cards);
// Two profiles should have been removed.
- ASSERT_EQ(2UL, profile_guids.size());
- EXPECT_EQ("00000000-0000-0000-0000-000000000000", profile_guids[0]);
- EXPECT_EQ("00000000-0000-0000-0000-000000000003", profile_guids[1]);
+ ASSERT_EQ(2UL, profiles.size());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000000", profiles[0]->guid());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000003", profiles[1]->guid());
// Make sure there are no profiles remaining.
sql::Statement s_autofill_profiles_empty(
@@ -1722,8 +1719,8 @@ TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) {
EXPECT_FALSE(s_autofill_profile_phones_empty.Step());
// One credit card should have been deleted.
- ASSERT_EQ(1UL, credit_card_guids.size());
- EXPECT_EQ("00000000-0000-0000-0000-000000000009", credit_card_guids[0]);
+ ASSERT_EQ(1UL, credit_cards.size());
+ EXPECT_EQ("00000000-0000-0000-0000-000000000009", credit_cards[0]->guid());
// There should be no cards left.
sql::Statement s_credit_cards_empty(
@@ -2677,12 +2674,12 @@ TEST_F(AutofillTableTest, DeleteUnmaskedCard) {
table_->UnmaskServerCreditCard(masked_card, full_number);
// Delete data in a range a year in the future.
- std::vector<std::string> profile_guids;
- std::vector<std::string> credit_card_guids;
+ std::vector<std::unique_ptr<AutofillProfile>> profiles;
+ std::vector<std::unique_ptr<CreditCard>> credit_cards;
ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween(
unmasked_time + base::TimeDelta::FromDays(365),
- unmasked_time + base::TimeDelta::FromDays(530),
- &profile_guids, &credit_card_guids));
+ unmasked_time + base::TimeDelta::FromDays(530), &profiles,
+ &credit_cards));
// This should not affect the unmasked card (should be unmasked).
std::vector<std::unique_ptr<CreditCard>> outputs;
@@ -2697,8 +2694,7 @@ TEST_F(AutofillTableTest, DeleteUnmaskedCard) {
// the database uses.
base::Time now = base::Time::Now() + base::TimeDelta::FromSeconds(1);
ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween(
- now - base::TimeDelta::FromDays(1), now,
- &profile_guids, &credit_card_guids));
+ now - base::TimeDelta::FromDays(1), now, &profiles, &credit_cards));
// This should re-mask.
ASSERT_TRUE(table_->GetServerCreditCards(&outputs));
@@ -2717,7 +2713,7 @@ TEST_F(AutofillTableTest, DeleteUnmaskedCard) {
// Delete all data.
ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween(
- base::Time(), base::Time::Max(), &profile_guids, &credit_card_guids));
+ base::Time(), base::Time::Max(), &profiles, &credit_cards));
// Should be masked again.
ASSERT_TRUE(table_->GetServerCreditCards(&outputs));
@@ -2911,8 +2907,8 @@ TEST_P(AutofillTableTestPerModelType, AutofillGetAllSyncMetadata) {
EntityMetadataMap metadata_records = metadata_batch.TakeAllMetadata();
EXPECT_EQ(metadata_records.size(), 2u);
- EXPECT_EQ(metadata_records[storage_key].sequence_number(), 1);
- EXPECT_EQ(metadata_records[storage_key2].sequence_number(), 2);
+ EXPECT_EQ(metadata_records[storage_key]->sequence_number(), 1);
+ EXPECT_EQ(metadata_records[storage_key2]->sequence_number(), 2);
// Now check that a model type state update replaces the old value
model_type_state.set_initial_sync_done(false);
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 5f511af4a6c..cf4486920bb 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
@@ -4,11 +4,14 @@
#include "components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h"
-#include <unordered_map>
+#include <map>
+#include <unordered_set>
#include <utility>
+#include <vector>
#include "base/base64.h"
#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/pickle.h"
#include "components/autofill/core/browser/autofill_metadata.h"
@@ -18,6 +21,7 @@
#include "components/autofill/core/browser/webdata/autofill_table.h"
#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_clock.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/sync/model/entity_data.h"
#include "components/sync/model/mutable_data_batch.h"
@@ -80,16 +84,17 @@ struct TypeAndMetadataId {
TypeAndMetadataId ParseWalletMetadataStorageKey(
const std::string& storage_key) {
- TypeAndMetadataId parsed;
-
base::Pickle pickle(storage_key.data(), storage_key.size());
base::PickleIterator iterator(pickle);
int type_int;
- if (!iterator.ReadInt(&type_int) ||
- !iterator.ReadString(&parsed.metadata_id)) {
+ std::string specifics_id;
+ if (!iterator.ReadInt(&type_int) || !iterator.ReadString(&specifics_id)) {
NOTREACHED() << "Unsupported storage_key provided " << storage_key;
}
+
+ TypeAndMetadataId parsed;
parsed.type = static_cast<WalletMetadataSpecifics::Type>(type_int);
+ parsed.metadata_id = GetMetadataIdForSpecificsId(specifics_id);
return parsed;
}
@@ -157,22 +162,22 @@ bool HasLocalBillingAddress(const AutofillMetadata& metadata) {
return metadata.billing_address_id.size() == kLocalGuidSize;
}
-bool IsRemoteBillingAddressEqualOrBetter(const AutofillMetadata& local,
- const AutofillMetadata& remote) {
- // If local is empty, remote is better (or equal). Otherwise, if remote is
- // empty, local is better.
- if (local.billing_address_id.empty()) {
+bool IsNewerBillingAddressEqualOrBetter(const AutofillMetadata& older,
+ const AutofillMetadata& newer) {
+ // If older is empty, newer is better (or equal). Otherwise, if newer is
+ // empty, older is better.
+ if (older.billing_address_id.empty()) {
return true;
- } else if (remote.billing_address_id.empty()) {
+ } else if (newer.billing_address_id.empty()) {
return false;
}
// Now we need to decide between non-empty profiles. Prefer id's pointing to
// local profiles over ids of non-local profiles.
- if (HasLocalBillingAddress(local) != HasLocalBillingAddress(remote)) {
- return HasLocalBillingAddress(remote);
+ if (HasLocalBillingAddress(older) != HasLocalBillingAddress(newer)) {
+ return HasLocalBillingAddress(newer);
}
- // For both local / both remote, we prefer the more recently used.
- return remote.use_date >= local.use_date;
+ // For both older / both newer, we prefer the more recently used.
+ return newer.use_date >= older.use_date;
}
AutofillMetadata MergeMetadata(WalletMetadataSpecifics::Type type,
@@ -187,7 +192,8 @@ AutofillMetadata MergeMetadata(WalletMetadataSpecifics::Type type,
merged.has_converted = local.has_converted || remote.has_converted;
break;
case WalletMetadataSpecifics::CARD:
- if (IsRemoteBillingAddressEqualOrBetter(local, remote)) {
+ if (IsNewerBillingAddressEqualOrBetter(/*older=*/local,
+ /*newer=*/remote)) {
merged.billing_address_id = remote.billing_address_id;
} else {
merged.billing_address_id = local.billing_address_id;
@@ -232,12 +238,25 @@ bool IsMetadataWorthUpdating(AutofillMetadata existing_entry,
if (!existing_entry.has_converted && new_entry.has_converted) {
return true;
}
- if (existing_entry.billing_address_id != new_entry.billing_address_id) {
+ if (existing_entry.billing_address_id != new_entry.billing_address_id &&
+ IsNewerBillingAddressEqualOrBetter(/*older=*/existing_entry,
+ /*newer=*/new_entry)) {
return true;
}
return false;
}
+bool IsAnyMetadataDeletable(
+ const std::map<std::string, AutofillMetadata>& metadata_map) {
+ for (const auto& pair : metadata_map) {
+ const AutofillMetadata& metadata = pair.second;
+ if (metadata.IsDeletable()) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool AddServerMetadata(AutofillTable* table,
WalletMetadataSpecifics::Type type,
const AutofillMetadata& metadata) {
@@ -269,7 +288,6 @@ bool RemoveServerMetadata(AutofillTable* table,
bool UpdateServerMetadata(AutofillTable* table,
WalletMetadataSpecifics::Type type,
const AutofillMetadata& metadata) {
- // TODO: Create UpdateServerAddressMetadata() that takes metadata as arg.
switch (type) {
case WalletMetadataSpecifics::ADDRESS:
return table->UpdateServerAddressMetadata(metadata);
@@ -318,6 +336,8 @@ AutofillWalletMetadataSyncBridge::AutofillWalletMetadataSyncBridge(
scoped_observer_.Add(web_data_backend_);
LoadDataCacheAndMetadata();
+
+ DeleteOldOrphanMetadata();
}
AutofillWalletMetadataSyncBridge::~AutofillWalletMetadataSyncBridge() {
@@ -388,12 +408,39 @@ std::string AutofillWalletMetadataSyncBridge::GetStorageKey(
entity_data.specifics.wallet_metadata().id());
}
+void AutofillWalletMetadataSyncBridge::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 data as well (i.e. the wallet metadata
+ // entities).
+ if (delete_metadata_change_list) {
+ for (const std::pair<std::string, AutofillMetadata>& pair : cache_) {
+ TypeAndMetadataId parsed_storage_key =
+ ParseWalletMetadataStorageKey(pair.first);
+ RemoveServerMetadata(GetAutofillTable(), parsed_storage_key.type,
+ parsed_storage_key.metadata_id);
+ }
+ cache_.clear();
+
+ // We do not notify the change to the UI because the data bridge will notify
+ // anyway and notifying on metadata deletion potentially before the data
+ // deletion is risky. This can cause another conversion of server addresses
+ // to local addresses as we lack the metadata (that it has been converted
+ // already).
+
+ // Commit the transaction to make sure the sync data (deleted here) and the
+ // sync metadata and the progress marker (deleted by the processor via
+ // |delete_metadata_change_list|) get wiped from the DB. This is especially
+ // important on Android where we cannot rely on committing transactions on
+ // shutdown).
+ web_data_backend_->CommitChanges();
+ }
+}
+
void AutofillWalletMetadataSyncBridge::AutofillProfileChanged(
const AutofillProfileChange& change) {
- // Skip local profiles (if possible, i.e. if it is not a deletion where
- // data_model() is not set).
- if (change.data_model() &&
- change.data_model()->record_type() != AutofillProfile::SERVER_PROFILE) {
+ // Skip local profiles.
+ if (change.data_model()->record_type() != AutofillProfile::SERVER_PROFILE) {
return;
}
LocalMetadataChanged(WalletMetadataSpecifics::ADDRESS, change);
@@ -429,10 +476,26 @@ void AutofillWalletMetadataSyncBridge::LoadDataCacheAndMetadata() {
for (const auto& it : addresses_metadata) {
cache_[GetStorageKeyForWalletMetadataTypeAndId(
WalletMetadataSpecifics::ADDRESS, it.first)] = it.second;
+ // TODO(crbug.com/949034): Consider adding standard functions for recording
+ // large times in seconds/minutes.
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Autofill.WalletUseDateInMinutes.Address",
+ /*sample=*/(AutofillClock::Now() - it.second.use_date).InMinutes(),
+ /*min=*/base::TimeDelta::FromMinutes(1).InMinutes(),
+ /*max=*/base::TimeDelta::FromDays(365).InMinutes(),
+ /*bucket_count=*/50);
}
for (const auto& it : cards_metadata) {
cache_[GetStorageKeyForWalletMetadataTypeAndId(
WalletMetadataSpecifics::CARD, it.first)] = it.second;
+ // TODO(crbug.com/949034): Consider adding standard functions for recording
+ // large times in seconds/minutes.
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Autofill.WalletUseDateInMinutes.Card",
+ /*sample=*/(AutofillClock::Now() - it.second.use_date).InMinutes(),
+ /*min=*/base::TimeDelta::FromMinutes(1).InMinutes(),
+ /*max=*/base::TimeDelta::FromDays(365).InMinutes(),
+ /*bucket_count=*/50);
}
// Load the metadata and send to the processor.
@@ -447,6 +510,62 @@ void AutofillWalletMetadataSyncBridge::LoadDataCacheAndMetadata() {
change_processor()->ModelReadyToSync(std::move(batch));
}
+void AutofillWalletMetadataSyncBridge::DeleteOldOrphanMetadata() {
+ if (!web_data_backend_ || !web_data_backend_->GetDatabase() ||
+ !GetAutofillTable()) {
+ // We have a problem with the database, not an issue, we clean up next time.
+ return;
+ }
+ if (!IsAnyMetadataDeletable(cache_)) {
+ return;
+ }
+
+ // Load up (metadata) ids for which data exists; we do not delete those.
+ std::unordered_set<std::string> non_orphan_ids;
+ std::vector<std::unique_ptr<AutofillProfile>> profiles;
+ std::vector<std::unique_ptr<CreditCard>> cards;
+ if (!GetAutofillTable()->GetServerProfiles(&profiles) ||
+ !GetAutofillTable()->GetServerCreditCards(&cards)) {
+ return;
+ }
+ for (const std::unique_ptr<AutofillProfile>& profile : profiles) {
+ non_orphan_ids.insert(profile->server_id());
+ }
+ for (const std::unique_ptr<CreditCard>& card : cards) {
+ non_orphan_ids.insert(card->server_id());
+ }
+
+ // Identify storage keys of old orphans (we delete them below to avoid
+ // modifying |cache_| while iterating).
+ std::unordered_set<std::string> old_orphan_keys;
+ for (const auto& pair : cache_) {
+ const AutofillMetadata& metadata = pair.second;
+ if (metadata.IsDeletable() && !non_orphan_ids.count(metadata.id)) {
+ old_orphan_keys.insert(pair.first);
+ }
+ }
+
+ if (old_orphan_keys.empty()) {
+ return;
+ }
+
+ std::unique_ptr<MetadataChangeList> metadata_change_list =
+ CreateMetadataChangeList();
+ for (const std::string storage_key : old_orphan_keys) {
+ TypeAndMetadataId parsed_storage_key =
+ ParseWalletMetadataStorageKey(storage_key);
+ if (RemoveServerMetadata(GetAutofillTable(), parsed_storage_key.type,
+ parsed_storage_key.metadata_id)) {
+ cache_.erase(storage_key);
+ change_processor()->Delete(storage_key, metadata_change_list.get());
+ }
+ }
+ // Commit the transaction to make sure the data and the metadata is written
+ // down (especially on Android where we cannot rely on committing transactions
+ // on shutdown).
+ web_data_backend_->CommitChanges();
+}
+
void AutofillWalletMetadataSyncBridge::GetDataImpl(
base::Optional<std::unordered_set<std::string>> storage_keys_set,
DataCallback callback) {
@@ -478,10 +597,10 @@ void AutofillWalletMetadataSyncBridge::UploadInitialLocalData(
local_keys_to_upload.insert(it.first);
}
// Strip |local_keys_to_upload| of the keys of data provided by the server.
- for (const EntityChange& change : entity_data) {
- DCHECK_EQ(change.type(), EntityChange::ACTION_ADD)
+ for (const std::unique_ptr<EntityChange>& change : entity_data) {
+ DCHECK_EQ(change->type(), EntityChange::ACTION_ADD)
<< "Illegal change; can only be called during initial MergeSyncData()";
- local_keys_to_upload.erase(change.storage_key());
+ local_keys_to_upload.erase(change->storage_key());
}
// Upload the remaining storage keys
for (const std::string& storage_key : local_keys_to_upload) {
@@ -502,24 +621,24 @@ AutofillWalletMetadataSyncBridge::MergeRemoteChanges(
AutofillTable* table = GetAutofillTable();
- for (const EntityChange& change : entity_data) {
+ for (const std::unique_ptr<EntityChange>& change : entity_data) {
TypeAndMetadataId parsed_storage_key =
- ParseWalletMetadataStorageKey(change.storage_key());
- switch (change.type()) {
+ ParseWalletMetadataStorageKey(change->storage_key());
+ switch (change->type()) {
case EntityChange::ACTION_ADD:
case EntityChange::ACTION_UPDATE: {
const WalletMetadataSpecifics& specifics =
- change.data().specifics.wallet_metadata();
+ change->data().specifics.wallet_metadata();
AutofillMetadata remote =
CreateAutofillMetadataFromWalletMetadataSpecifics(specifics);
- auto it = cache_.find(change.storage_key());
+ auto it = cache_.find(change->storage_key());
base::Optional<AutofillMetadata> local = base::nullopt;
if (it != cache_.end()) {
local = it->second;
}
if (!local) {
- cache_[change.storage_key()] = remote;
+ cache_[change->storage_key()] = remote;
is_any_local_modified |= AddServerMetadata(
GetAutofillTable(), parsed_storage_key.type, remote);
continue;
@@ -529,12 +648,12 @@ AutofillWalletMetadataSyncBridge::MergeRemoteChanges(
AutofillMetadata merged =
MergeMetadata(parsed_storage_key.type, *local, remote);
if (merged != *local) {
- cache_[change.storage_key()] = merged;
+ cache_[change->storage_key()] = merged;
is_any_local_modified |=
UpdateServerMetadata(table, parsed_storage_key.type, merged);
}
if (merged != remote) {
- change_processor()->Put(change.storage_key(),
+ change_processor()->Put(change->storage_key(),
CreateEntityDataFromAutofillMetadata(
parsed_storage_key.type, merged),
metadata_change_list.get());
@@ -542,14 +661,27 @@ AutofillWalletMetadataSyncBridge::MergeRemoteChanges(
break;
}
case EntityChange::ACTION_DELETE: {
- cache_.erase(change.storage_key());
- is_any_local_modified |= RemoveServerMetadata(
- table, parsed_storage_key.type, parsed_storage_key.metadata_id);
+ // We intentionally ignore remote deletions in order to avoid
+ // delete-create ping pongs (if we delete metadata for address data
+ // entity that still locally exists, PDM will think the server address
+ // has not been converted to a local address yet and will trigger
+ // conversion that in turn triggers creating and committing the metadata
+ // entity again).
+ // This is safe because this client will delete the wallet_metadata
+ // entity locally as soon as the wallet_data entity gets deleted.
+ // Corner cases are handled by DeleteOldOrphanMetadata().
break;
}
}
}
+ // 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 committing transactions on shutdown). We need to commit
+ // even if !|is_any_local_modified| because the model type state or local
+ // metadata may have changed.
+ web_data_backend_->CommitChanges();
+
if (is_any_local_modified) {
web_data_backend_->NotifyOfMultipleAutofillChanges();
}
@@ -576,9 +708,7 @@ void AutofillWalletMetadataSyncBridge::LocalMetadataChanged(
if (RemoveServerMetadata(GetAutofillTable(), type, metadata_id)) {
cache_.erase(storage_key);
// Send up deletion only if we had this entry in the DB. It is not there
- // if (i) it was previously deleted by a remote deletion or (ii) this is
- // notification for a LOCAL_PROFILE (which have non-overlapping
- // storage_keys).
+ // if it was previously deleted by a remote deletion.
change_processor()->Delete(storage_key, metadata_change_list.get());
}
return;
@@ -612,6 +742,11 @@ void AutofillWalletMetadataSyncBridge::LocalMetadataChanged(
metadata_change_list.get());
return;
}
+
+ // We do not need to commit any local changes (written by the processor via
+ // the metadata change list) because the open WebDatabase transaction is
+ // committed by the AutofillWebDataService when the original local write
+ // operation (that triggered this notification to the bridge) finishes.
}
} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h
index 16feaf2dd78..59428a945ba 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h
@@ -74,6 +74,8 @@ class AutofillWalletMetadataSyncBridge
void GetAllDataForDebugging(DataCallback callback) override;
std::string GetClientTag(const syncer::EntityData& entity_data) override;
std::string GetStorageKey(const syncer::EntityData& entity_data) override;
+ void ApplyStopSyncChanges(std::unique_ptr<syncer::MetadataChangeList>
+ delete_metadata_change_list) override;
// AutofillWebDataServiceObserverOnDBSequence implementation.
void AutofillProfileChanged(const AutofillProfileChange& change) override;
@@ -88,6 +90,16 @@ class AutofillWalletMetadataSyncBridge
// tracking changes.
void LoadDataCacheAndMetadata();
+ // Deletes old metadata entities that have no corresponding data entities.
+ // This routine is here to help with really corner-case scenarios, e.g.
+ // - having one client create a metadata entity M for new data D while other
+ // clients are off;
+ // - switch off this client forever and remove the entity D from Wallet;
+ // - turn on other clients so that they receive M from sync;
+ // - these other clients never knew about D and thus they have no reason to
+ // delete M when they receive an update from the Walllet server.
+ void DeleteOldOrphanMetadata();
+
// Reads local wallet metadata from the database and passes them into
// |callback|. If |storage_keys_set| is not set, it returns all data entries.
// Otherwise, it returns only entries with storage key in |storage_keys_set|.
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 a9322372bcb..c887bde454f 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
@@ -19,6 +19,7 @@
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
+#include "components/autofill/core/browser/autofill_metadata.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/credit_card.h"
@@ -44,7 +45,6 @@ using base::ScopedTempDir;
using sync_pb::WalletMetadataSpecifics;
using syncer::DataBatch;
using syncer::EntityData;
-using syncer::EntityDataPtr;
using syncer::KeyAndData;
using syncer::MockModelTypeChangeProcessor;
using syncer::ModelType;
@@ -85,13 +85,14 @@ 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);
base::Time UseDateFromProtoValue(int64_t use_date_proto_value) {
return base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromMicroseconds(use_date_proto_value));
}
+const base::Time kDefaultTime = UseDateFromProtoValue(100);
+
int64_t UseDateToProtoValue(base::Time use_date) {
return use_date.ToDeltaSinceWindowsEpoch().InMicroseconds();
}
@@ -127,7 +128,7 @@ WalletMetadataSpecifics CreateWalletMetadataSpecificsForAddress(
// clock value is overrided by TestAutofillClock in the test fixture).
return CreateWalletMetadataSpecificsForAddressWithDetails(
specifics_id, /*use_count=*/1,
- /*use_date=*/UseDateToProtoValue(kJune2017));
+ /*use_date=*/UseDateToProtoValue(kDefaultTime));
}
WalletMetadataSpecifics CreateWalletMetadataSpecificsForCardWithDetails(
@@ -152,7 +153,7 @@ WalletMetadataSpecifics CreateWalletMetadataSpecificsForCard(
// clock value is overrided by TestAutofillClock in the test fixture).
return CreateWalletMetadataSpecificsForCardWithDetails(
specifics_id, /*use_count=*/1,
- /*use_date=*/UseDateToProtoValue(kJune2017));
+ /*use_date=*/UseDateToProtoValue(kDefaultTime));
}
AutofillProfile CreateServerProfileWithDetails(const std::string& server_id,
@@ -265,7 +266,7 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
void SetUp() override {
// Fix a time for implicitly constructed use_dates in AutofillProfile.
- test_clock_.SetNow(kJune2017);
+ test_clock_.SetNow(kDefaultTime);
CountryNames::SetLocaleString(kLocaleString);
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
db_.AddTable(&table_);
@@ -291,6 +292,12 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
mock_processor_.CreateForwardingProcessor(), &backend_));
}
+ void StopSyncing() {
+ real_processor_->OnSyncStopping(syncer::CLEAR_METADATA);
+ }
+
+ void Shutdown() { real_processor_->OnSyncStopping(syncer::KEEP_METADATA); }
+
void StartSyncing(
const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
base::RunLoop loop;
@@ -307,8 +314,7 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
ReceiveUpdates(remote_data);
}
- void ReceiveUpdates(
- const std::vector<WalletMetadataSpecifics>& 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;
@@ -320,22 +326,48 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
for (const WalletMetadataSpecifics& specifics : remote_data) {
updates.push_back(SpecificsToUpdateResponse(specifics));
}
- real_processor_->OnUpdateReceived(state, updates);
+ real_processor_->OnUpdateReceived(state, std::move(updates));
}
- EntityData SpecificsToEntity(const WalletMetadataSpecifics& specifics) {
- EntityData data;
- *data.specifics.mutable_wallet_metadata() = specifics;
- data.client_tag_hash = syncer::GenerateSyncableHash(
- syncer::AUTOFILL_WALLET_METADATA, bridge()->GetClientTag(data));
+ void ReceiveTombstones(
+ const std::vector<WalletMetadataSpecifics>& remote_tombstones) {
+ // 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_tombstones) {
+ updates.push_back(
+ SpecificsToUpdateResponse(specifics, /*is_deleted=*/true));
+ }
+ real_processor_->OnUpdateReceived(state, std::move(updates));
+ }
+
+ std::unique_ptr<EntityData> SpecificsToEntity(
+ const WalletMetadataSpecifics& specifics,
+ bool is_deleted = false) {
+ auto data = std::make_unique<EntityData>();
+ *data->specifics.mutable_wallet_metadata() = specifics;
+ data->client_tag_hash = syncer::GenerateSyncableHash(
+ syncer::AUTOFILL_WALLET_METADATA, bridge()->GetClientTag(*data));
+ if (is_deleted) {
+ // Specifics had to be set in order to generate the client tag. Since
+ // deleted entity is defined by specifics being empty, we need to clear
+ // them now.
+ data->specifics = sync_pb::EntitySpecifics();
+ }
return data;
}
- syncer::UpdateResponseData SpecificsToUpdateResponse(
- const WalletMetadataSpecifics& specifics) {
- syncer::UpdateResponseData data;
- data.entity = SpecificsToEntity(specifics).PassToPtr();
- data.response_version = response_version;
+ std::unique_ptr<syncer::UpdateResponseData> SpecificsToUpdateResponse(
+ const WalletMetadataSpecifics& specifics,
+ bool is_deleted = false) {
+ auto data = std::make_unique<syncer::UpdateResponseData>();
+ data->entity = SpecificsToEntity(specifics, is_deleted);
+ data->response_version = response_version;
return data;
}
@@ -380,12 +412,35 @@ class AutofillWalletMetadataSyncBridgeTest : public testing::Test {
return data;
}
+ std::vector<std::string> GetLocalSyncMetadataStorageKeys() {
+ std::vector<std::string> storage_keys;
+
+ AutofillTable* table = AutofillTable::FromWebDatabase(&db_);
+ syncer::MetadataBatch batch;
+ if (table->GetAllSyncMetadata(syncer::AUTOFILL_WALLET_METADATA, &batch)) {
+ for (const std::pair<const std::string,
+ std::unique_ptr<sync_pb::EntityMetadata>>& entry :
+ batch.GetAllMetadata()) {
+ storage_keys.push_back(entry.first);
+ }
+ }
+ return storage_keys;
+ }
+
+ void AdvanceTestClockByTwoYears() {
+ test_clock_.Advance(base::TimeDelta::FromDays(365 * 2));
+ }
+
AutofillWalletMetadataSyncBridge* bridge() { return bridge_.get(); }
syncer::MockModelTypeChangeProcessor& mock_processor() {
return mock_processor_;
}
+ syncer::ClientTagBasedModelTypeProcessor* real_processor() {
+ return real_processor_.get();
+ }
+
AutofillTable* table() { return &table_; }
MockAutofillWebDataBackend* backend() { return &backend_; }
@@ -410,7 +465,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForAddress) {
ResetBridge();
WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForAddress(kAddr1SpecificsId);
- EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
+ EXPECT_EQ(bridge()->GetClientTag(*SpecificsToEntity(specifics)),
kAddr1SyncTag);
}
@@ -418,7 +473,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetClientTagForCard) {
ResetBridge();
WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForCard(kCard1SpecificsId);
- EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
+ EXPECT_EQ(bridge()->GetClientTag(*SpecificsToEntity(specifics)),
kCard1SyncTag);
}
@@ -427,7 +482,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForAddress) {
ResetBridge();
WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForAddress(kAddr1SpecificsId);
- EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics)),
+ EXPECT_EQ(bridge()->GetStorageKey(*SpecificsToEntity(specifics)),
GetAddressStorageKey(kAddr1SpecificsId));
}
@@ -435,7 +490,7 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetStorageKeyForCard) {
ResetBridge();
WalletMetadataSpecifics specifics =
CreateWalletMetadataSpecificsForCard(kCard1SpecificsId);
- EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics)),
+ EXPECT_EQ(bridge()->GetStorageKey(*SpecificsToEntity(specifics)),
GetCardStorageKey(kCard1SpecificsId));
}
@@ -516,6 +571,50 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, GetData_ShouldReturnCompleteData) {
EqualsSpecifics(card_specifics)));
}
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ ApplyStopSyncChanges_ShouldWipeLocalDataWhenSyncStopped) {
+ // Perform initial sync to create sync data & metadata.
+ ResetBridge(/*initial_sync_done=*/false);
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+ StartSyncing({profile, card});
+
+ // Now stop sync. This should wipe the data but not notify the backend (as the
+ // data bridge will do that).
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ StopSyncing();
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
+}
+
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ ApplyStopSyncChanges_ShouldKeepLocalDataOnShutdown) {
+ // Perform initial sync to create sync data & metadata.
+ ResetBridge(/*initial_sync_done=*/false);
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+ StartSyncing({profile, card});
+
+ // Now simulate shutting down the browser. This should not touch any of the
+ // data and thus also not notify the backend.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ Shutdown();
+
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
// Verify that lower values of metadata are not sent to the sync server when
// local metadata is updated.
TEST_F(AutofillWalletMetadataSyncBridgeTest,
@@ -532,6 +631,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
kCard1ServerId, /*use_count=*/2, /*use_date=*/5);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ // Local changes should not cause local DB writes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillProfileChanged(
AutofillProfileChange(AutofillProfileChange::UPDATE,
@@ -567,6 +669,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
kCard1ServerId, /*use_count=*/2, /*use_date=*/5);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ // Local changes should not cause local DB writes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillProfileChanged(
AutofillProfileChange(AutofillProfileChange::ADD,
@@ -611,6 +716,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
Put(kAddr1StorageKey, HasSpecifics(expected_profile_specifics), _));
EXPECT_CALL(mock_processor(),
Put(kCard1StorageKey, HasSpecifics(expected_card_specifics), _));
+ // Local changes should not cause local DB writes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillProfileChanged(
AutofillProfileChange(AutofillProfileChange::UPDATE,
@@ -645,6 +753,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
Put(kAddr1StorageKey, HasSpecifics(expected_profile_specifics), _));
EXPECT_CALL(mock_processor(),
Put(kCard1StorageKey, HasSpecifics(expected_card_specifics), _));
+ // Local changes should not cause local DB writes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillProfileChanged(AutofillProfileChange(
AutofillProfileChange::ADD, new_profile.server_id(), &new_profile));
@@ -679,6 +790,9 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest, SendNewDataToServerOnLocalUpdate) {
Put(kAddr1StorageKey, HasSpecifics(expected_profile_specifics), _));
EXPECT_CALL(mock_processor(),
Put(kCard1StorageKey, HasSpecifics(expected_card_specifics), _));
+ // Local changes should not cause local DB writes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
bridge()->AutofillProfileChanged(AutofillProfileChange(
AutofillProfileChange::UPDATE, new_profile.server_id(), &new_profile));
@@ -704,11 +818,15 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
EXPECT_CALL(mock_processor(), Delete(kAddr1StorageKey, _));
EXPECT_CALL(mock_processor(), Delete(kCard1StorageKey, _));
+ // Local changes should not cause local DB writes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
- bridge()->AutofillProfileChanged(AutofillProfileChange(
- AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr));
+ bridge()->AutofillProfileChanged(
+ AutofillProfileChange(AutofillProfileChange::REMOVE,
+ existing_profile.server_id(), &existing_profile));
bridge()->CreditCardChanged(CreditCardChange(
- CreditCardChange::REMOVE, existing_card.server_id(), nullptr));
+ CreditCardChange::REMOVE, existing_card.server_id(), &existing_card));
// Check that there is no metadata anymore.
EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
@@ -730,16 +848,230 @@ TEST_F(AutofillWalletMetadataSyncBridgeTest,
ASSERT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ // Local changes should not cause local DB writes.
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
- bridge()->AutofillProfileChanged(AutofillProfileChange(
- AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr));
+ bridge()->AutofillProfileChanged(
+ AutofillProfileChange(AutofillProfileChange::REMOVE,
+ existing_profile.server_id(), &existing_profile));
bridge()->CreditCardChanged(CreditCardChange(
- CreditCardChange::REMOVE, existing_card.server_id(), nullptr));
+ CreditCardChange::REMOVE, existing_card.server_id(), &existing_card));
// Check that there is also no metadata at the end.
EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
}
+// Verify that old orphan metadata gets deleted on startup.
+TEST_F(AutofillWalletMetadataSyncBridgeTest, DeleteOldOrphanMetadataOnStartup) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+
+ // Save only metadata and not data - simulate an orphan.
+ table()->AddServerAddressMetadata(
+ CreateServerProfileFromSpecifics(profile).GetMetadata());
+ table()->AddServerCardMetadata(
+ CreateServerCreditCardFromSpecifics(card).GetMetadata());
+
+ // Make the orphans old by advancing time.
+ AdvanceTestClockByTwoYears();
+
+ EXPECT_CALL(mock_processor(), Delete(kAddr1StorageKey, _));
+ EXPECT_CALL(mock_processor(), Delete(kCard1StorageKey, _));
+ EXPECT_CALL(*backend(), CommitChanges());
+
+ ResetBridge();
+
+ ASSERT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
+}
+
+// Verify that recent orphan metadata does not get deleted on startup.
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ DoNotDeleteOldNonOrphanMetadataOnStartup) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+
+ // Save both data and metadata - these are not orphans.
+ table()->SetServerProfiles({CreateServerProfileFromSpecifics(profile)});
+ table()->SetServerCreditCards({CreateServerCreditCardFromSpecifics(card)});
+
+ // Make the entities old by advancing time.
+ AdvanceTestClockByTwoYears();
+
+ // Since the entities are non-oprhans, they should not get deleted.
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+
+ ResetBridge();
+
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
+// Verify that recent orphan metadata does not get deleted on startup.
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ DoNotDeleteRecentOrphanMetadataOnStartup) {
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+
+ // Save only metadata and not data - simulate an orphan.
+ table()->AddServerAddressMetadata(
+ CreateServerProfileFromSpecifics(profile).GetMetadata());
+ table()->AddServerCardMetadata(
+ CreateServerCreditCardFromSpecifics(card).GetMetadata());
+
+ // We do not advance time so the orphans are recent, should not get deleted.
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges()).Times(0);
+
+ ResetBridge();
+
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
+// Test that both local cards and local profiles that are not in the remote data
+// set are uploaded during initial sync. This should rarely happen in practice
+// because we wipe local data when disabling sync. Still there are corner cases
+// such as when PDM manages to change metadata before the metadata bridge
+// performs initial sync.
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ InitialSync_UploadUniqueLocalData) {
+ WalletMetadataSpecifics preexisting_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics preexisting_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+
+ table()->SetServerProfiles(
+ {CreateServerProfileFromSpecifics(preexisting_profile)});
+ table()->SetServerCreditCards(
+ {CreateServerCreditCardFromSpecifics(preexisting_card)});
+
+ // Have different entities on the server.
+ WalletMetadataSpecifics remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr2SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard2SpecificsId, /*use_count=*/30, /*use_date=*/40);
+
+ // The bridge should upload the unique local entities and store the remote
+ // ones locally.
+ EXPECT_CALL(mock_processor(),
+ Put(kAddr1StorageKey, HasSpecifics(preexisting_profile), _));
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(preexisting_card), _));
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
+ ResetBridge(/*initial_sync_done=*/false);
+ StartSyncing({remote_profile, remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(preexisting_profile),
+ EqualsSpecifics(preexisting_card),
+ EqualsSpecifics(remote_profile),
+ EqualsSpecifics(remote_card)));
+}
+
+// Test that the initial sync correctly distinguishes data that is unique in the
+// local data set from data that is both in the local data and in the remote
+// data. We should only upload the local data. This should rarely happen in
+// practice because we wipe local data when disabling sync. Still there are
+// corner cases such as when PDM manages to change metadata before the metadata
+// bridge performs initial sync.
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ InitialSync_UploadOnlyUniqueLocalData) {
+ WalletMetadataSpecifics preexisting_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics preexisting_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+
+ table()->SetServerProfiles(
+ {CreateServerProfileFromSpecifics(preexisting_profile)});
+ table()->SetServerCreditCards(
+ {CreateServerCreditCardFromSpecifics(preexisting_card)});
+
+ // The remote profile has the same id as local profile, only is newer.
+ WalletMetadataSpecifics remote_profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/15, /*use_date=*/25);
+ WalletMetadataSpecifics remote_card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard2SpecificsId, /*use_count=*/30, /*use_date=*/40);
+
+ // Upload _only_ the unique local data, only the card.
+ EXPECT_CALL(mock_processor(),
+ Put(kCard1StorageKey, HasSpecifics(preexisting_card), _));
+ EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
+
+ ResetBridge(/*initial_sync_done=*/false);
+ StartSyncing({remote_profile, remote_card});
+
+ EXPECT_THAT(GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(preexisting_card),
+ EqualsSpecifics(remote_profile),
+ EqualsSpecifics(remote_card)));
+}
+
+// Test that remote deletions are ignored.
+TEST_F(AutofillWalletMetadataSyncBridgeTest,
+ RemoteDeletion_ShouldNotDeleteExistingLocalData) {
+ // Perform initial sync to create sync data & metadata.
+ ResetBridge(/*initial_sync_done=*/false);
+ WalletMetadataSpecifics profile =
+ CreateWalletMetadataSpecificsForAddressWithDetails(
+ kAddr1SpecificsId, /*use_count=*/10, /*use_date=*/20);
+ WalletMetadataSpecifics card =
+ CreateWalletMetadataSpecificsForCardWithDetails(
+ kCard1SpecificsId, /*use_count=*/30, /*use_date=*/40);
+ StartSyncing({profile, card});
+
+ // Verify that both the processor and the local DB contain sync metadata.
+ ASSERT_TRUE(real_processor()->IsTrackingEntityForTest(kAddr1StorageKey));
+ ASSERT_TRUE(real_processor()->IsTrackingEntityForTest(kCard1StorageKey));
+ ASSERT_THAT(GetLocalSyncMetadataStorageKeys(),
+ UnorderedElementsAre(kAddr1StorageKey, kCard1StorageKey));
+
+ // Now delete the profile.
+ // We still need to commit the updated progress marker and sync metadata.
+ EXPECT_CALL(*backend(), CommitChanges());
+ // Changes should _not_ happen in the local autofill database.
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ ReceiveTombstones({profile, card});
+
+ // Verify that even though the processor does not track these entities any
+ // more and the sync metadata is gone, the actual data entities still exist in
+ // the local DB.
+ EXPECT_FALSE(real_processor()->IsTrackingEntityForTest(kAddr1StorageKey));
+ EXPECT_FALSE(real_processor()->IsTrackingEntityForTest(kCard1StorageKey));
+ EXPECT_THAT(GetLocalSyncMetadataStorageKeys(), IsEmpty());
+ EXPECT_THAT(
+ GetAllLocalDataInclRestart(),
+ UnorderedElementsAre(EqualsSpecifics(profile), EqualsSpecifics(card)));
+}
+
enum RemoteChangesMode {
INITIAL_SYNC_ADD, // Initial sync -> ADD changes.
LATER_SYNC_ADD, // Later sync; the client receives the data for the first
@@ -759,8 +1091,7 @@ class AutofillWalletMetadataSyncBridgeRemoteChangesTest
void ResetBridgeWithPotentialInitialSync(
const std::vector<WalletMetadataSpecifics>& remote_data) {
- AutofillWalletMetadataSyncBridgeTest::ResetBridge(
- /*initial_sync_done=*/GetParam() != INITIAL_SYNC_ADD);
+ ResetBridge(/*initial_sync_done=*/GetParam() != INITIAL_SYNC_ADD);
if (GetParam() == LATER_SYNC_UPDATE) {
StartSyncing(remote_data);
@@ -768,11 +1099,11 @@ class AutofillWalletMetadataSyncBridgeRemoteChangesTest
}
void ReceivePotentiallyInitialUpdates(
- const std::vector<WalletMetadataSpecifics>& remote_data = {}) {
+ const std::vector<WalletMetadataSpecifics>& remote_data) {
if (GetParam() != LATER_SYNC_UPDATE) {
StartSyncing(remote_data);
} else {
- AutofillWalletMetadataSyncBridgeTest::ReceiveUpdates(remote_data);
+ ReceiveUpdates(remote_data);
}
}
@@ -783,10 +1114,14 @@ class AutofillWalletMetadataSyncBridgeRemoteChangesTest
// No upstream communication or local DB change happens if the server sends an
// empty update.
TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest, EmptyUpdateIgnored) {
+ ResetBridgeWithPotentialInitialSync({});
+
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker.
+ EXPECT_CALL(*backend(), CommitChanges());
- ResetBridgeWithPotentialInitialSync({});
ReceivePotentiallyInitialUpdates({});
EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
@@ -808,6 +1143,9 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest, SameDataIgnored) {
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker.
+ EXPECT_CALL(*backend(), CommitChanges());
ReceivePotentiallyInitialUpdates({profile, card});
@@ -840,6 +1178,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates(
{updated_remote_profile, updated_remote_card});
@@ -875,6 +1215,9 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(),
Put(kAddr1StorageKey, HasSpecifics(profile), _));
EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker.
+ EXPECT_CALL(*backend(), CommitChanges());
ReceivePotentiallyInitialUpdates(
{updated_remote_profile, updated_remote_card});
@@ -918,6 +1261,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
EXPECT_CALL(mock_processor(),
Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates(
{updated_remote_profile, updated_remote_card});
@@ -962,6 +1307,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
EXPECT_CALL(mock_processor(),
Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates(
{updated_remote_profile, updated_remote_card});
@@ -995,6 +1342,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates(
{updated_remote_profile, updated_remote_card});
@@ -1024,6 +1373,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1051,6 +1402,9 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker.
+ EXPECT_CALL(*backend(), CommitChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1078,6 +1432,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1105,6 +1461,9 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker.
+ EXPECT_CALL(*backend(), CommitChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1132,6 +1491,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1159,6 +1520,9 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(kCard1StorageKey, HasSpecifics(card), _));
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker.
+ EXPECT_CALL(*backend(), CommitChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1195,6 +1559,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(),
Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1231,6 +1597,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(),
Put(kCard1StorageKey, HasSpecifics(merged_card), _));
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_card});
@@ -1258,6 +1626,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_profile});
@@ -1285,6 +1655,9 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(),
Put(kAddr1StorageKey, HasSpecifics(profile), _));
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0);
+ // We still need to commit the updated progress marker.
+ EXPECT_CALL(*backend(), CommitChanges());
ReceivePotentiallyInitialUpdates({updated_remote_profile});
@@ -1319,6 +1692,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(),
Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_profile});
@@ -1353,6 +1728,8 @@ TEST_P(AutofillWalletMetadataSyncBridgeRemoteChangesTest,
EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
EXPECT_CALL(mock_processor(),
Put(kAddr1StorageKey, HasSpecifics(merged_profile), _));
+ EXPECT_CALL(*backend(), CommitChanges());
+ EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
ReceivePotentiallyInitialUpdates({updated_remote_profile});
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 7b88c1b8b36..e577d9565b9 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
@@ -7,12 +7,14 @@
#include <stddef.h>
#include <utility>
+#include <vector>
#include "base/base64.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_data_model.h"
@@ -22,6 +24,7 @@
#include "components/autofill/core/browser/webdata/autofill_table.h"
#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_clock.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/sync/model/sync_change.h"
#include "components/sync/model/sync_change_processor.h"
@@ -362,6 +365,12 @@ void AutofillWalletMetadataSyncableService::OnWalletDataTrackingStateChanged(
}
}
+void AutofillWalletMetadataSyncableService::WaitUntilReadyToSync(
+ base::OnceClosure done) {
+ // Not used in the legacy directory-based architecture.
+ NOTREACHED();
+}
+
syncer::SyncMergeResult
AutofillWalletMetadataSyncableService::MergeDataAndStartSyncing(
syncer::ModelType type,
@@ -383,6 +392,39 @@ AutofillWalletMetadataSyncableService::MergeDataAndStartSyncing(
result = MergeData(initial_sync_data);
}
+ // Record ages for individual metadata entities to UMA.
+ for (const syncer::SyncData& data : cache_) {
+ const sync_pb::WalletMetadataSpecifics& specifics =
+ data.GetSpecifics().wallet_metadata();
+ base::Time use_date = base::Time::FromDeltaSinceWindowsEpoch(
+ base::TimeDelta::FromMicroseconds(specifics.use_date()));
+ switch (specifics.type()) {
+ case sync_pb::WalletMetadataSpecifics::ADDRESS:
+ // TODO(crbug.com/949034): Consider adding standard functions for
+ // recording large times in seconds/minutes.
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Autofill.WalletUseDateInMinutes.Address",
+ /*sample=*/(AutofillClock::Now() - use_date).InMinutes(),
+ /*min=*/base::TimeDelta::FromMinutes(1).InMinutes(),
+ /*max=*/base::TimeDelta::FromDays(365).InMinutes(),
+ /*bucket_count=*/50);
+ break;
+ case sync_pb::WalletMetadataSpecifics::CARD:
+ // TODO(crbug.com/949034): Consider adding standard functions for
+ // recording large times in seconds/minutes.
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Autofill.WalletUseDateInMinutes.Card",
+ /*sample=*/(AutofillClock::Now() - use_date).InMinutes(),
+ /*min=*/base::TimeDelta::FromMinutes(1).InMinutes(),
+ /*max=*/base::TimeDelta::FromDays(365).InMinutes(),
+ /*bucket_count=*/50);
+ break;
+ case sync_pb::WalletMetadataSpecifics::UNKNOWN:
+ NOTREACHED();
+ break;
+ }
+ }
+
// Notify that sync has started. This callback does not currently take into
// account whether we're actually tracking wallet data.
if (web_data_backend_)
@@ -507,8 +549,8 @@ syncer::SyncError AutofillWalletMetadataSyncableService::ProcessSyncChanges(
status = SendChangesToSyncServer(changes_to_sync);
if (is_any_local_modified) {
// TODO(crbug.com/900607): Remove the need to listen to
- // AutofillMultipleChanged() in the new USS implementation so that we can
- // get rid of this hack.
+ // AutofillMultipleChangedBySync() in the new USS implementation so that we
+ // can get rid of this hack.
DCHECK(!ignore_multiple_changed_notification_);
ignore_multiple_changed_notification_ = true;
web_data_backend_->NotifyOfMultipleAutofillChanges();
@@ -521,19 +563,18 @@ syncer::SyncError AutofillWalletMetadataSyncableService::ProcessSyncChanges(
void AutofillWalletMetadataSyncableService::AutofillProfileChanged(
const AutofillProfileChange& change) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(change.data_model());
if (!track_wallet_data_) {
return;
}
- if (sync_processor_ && change.data_model() &&
+ if (sync_processor_ && change.type() == AutofillProfileChange::UPDATE &&
change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) {
std::string server_id = GetServerId(*change.data_model());
auto it = FindServerIdAndTypeInCache(
server_id, sync_pb::WalletMetadataSpecifics::ADDRESS, &cache_);
if (it == cache_.end())
return;
- // Implicitly, we filter out ADD (not in cache) and REMOVE (!data_model()).
- DCHECK(change.type() == AutofillProfileChange::UPDATE);
const sync_pb::WalletMetadataSpecifics& remote =
it->GetSpecifics().wallet_metadata();
@@ -568,7 +609,7 @@ void AutofillWalletMetadataSyncableService::CreditCardChanged(
if (it == cache_.end())
return;
// Deletions and creations are treated by Wallet data sync (and propagated
- // here by AutofillMultipleChanged()). We only treat updates here.
+ // here by AutofillMultipleChangedBySync()). We only treat updates here.
if (change.type() != AutofillProfileChange::UPDATE) {
return;
}
@@ -589,11 +630,11 @@ void AutofillWalletMetadataSyncableService::CreditCardChanged(
}
}
-void AutofillWalletMetadataSyncableService::AutofillMultipleChanged() {
+void AutofillWalletMetadataSyncableService::AutofillMultipleChangedBySync() {
if (ignore_multiple_changed_notification_) {
// TODO(crbug.com/900607): Remove the need to listen to
- // AutofillMultipleChanged() in the new USS implementation so that we can
- // get rid of this hack.
+ // AutofillMultipleChangedBySync() in the new USS implementation so that we
+ // can get rid of this hack.
return;
}
@@ -754,8 +795,8 @@ syncer::SyncMergeResult AutofillWalletMetadataSyncableService::MergeData(
result.set_error(SendChangesToSyncServer(changes_to_sync));
if (is_any_local_modified) {
// TODO(crbug.com/900607): Remove the need to listen to
- // AutofillMultipleChanged() in the new USS implementation so that we can
- // get rid of this hack.
+ // AutofillMultipleChangedBySync() in the new USS implementation so that we
+ // can get rid of this hack.
DCHECK(!ignore_multiple_changed_notification_);
ignore_multiple_changed_notification_ = true;
web_data_backend_->NotifyOfMultipleAutofillChanges();
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h
index 0169b0deb07..0f963a71ebe 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h
@@ -64,6 +64,7 @@ class AutofillWalletMetadataSyncableService
}
// syncer::SyncableService implementation.
+ void WaitUntilReadyToSync(base::OnceClosure done) override;
syncer::SyncMergeResult MergeDataAndStartSyncing(
syncer::ModelType type,
const syncer::SyncDataList& initial_sync_data,
@@ -78,7 +79,7 @@ class AutofillWalletMetadataSyncableService
// AutofillWebDataServiceObserverOnDBSequence implementation.
void AutofillProfileChanged(const AutofillProfileChange& change) override;
void CreditCardChanged(const CreditCardChange& change) override;
- void AutofillMultipleChanged() override;
+ void AutofillMultipleChangedBySync() override;
// Creates a new AutofillWalletMetadataSyncableService and hangs it off of
// |web_data_service|, which takes ownership. This method should only be
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service_unittest.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service_unittest.cc
index bd930b38b5a..39b72ca2ffe 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service_unittest.cc
@@ -597,7 +597,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest, AddToServerOnMultiChange) {
sync_pb::WalletMetadataSpecifics::CARD,
kCard2Utf8, 7, 8, kAddr2Utf8))));
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that higher values of existing metadata are sent to the sync server
@@ -623,7 +623,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
sync_pb::WalletMetadataSpecifics::CARD,
kCard1Utf8, 7, 8, kAddr2Utf8))));
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that lower values of existing metadata are not sent to the sync server
@@ -641,7 +641,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
EXPECT_CALL(local_, SendChangesToSyncServer(_)).Times(0);
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that erased local metadata is also erased from the sync server when
@@ -663,7 +663,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
SyncChangeMatches(syncer::SyncChange::ACTION_DELETE,
kCard1SyncTag))));
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that erased local metadata is not erased from the sync server when
@@ -682,7 +682,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
EXPECT_CALL(local_, SendChangesToSyncServer(_)).Times(0);
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that erased local metadata is also erased from the sync server when
@@ -706,7 +706,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
SyncChangeMatches(syncer::SyncChange::ACTION_DELETE,
kCard1SyncTag))));
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
local_.OnWalletDataTrackingStateChanged(true);
}
@@ -1001,7 +1001,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
SyncChangeMatches(syncer::SyncChange::ACTION_DELETE,
kCard2SyncTag))));
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that Wallet data arriving after metadata will not send lower metadata
@@ -1028,7 +1028,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
AutofillCardMetadataMatches(kCard1, 7, 8, kAddr2)));
EXPECT_CALL(local_, SendChangesToSyncServer(_)).Times(0);
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that processing a small subset of metadata changes before any Wallet
@@ -1072,7 +1072,7 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
AutofillCardMetadataMatches(kCard2, 15, 16, kAddr1)));
EXPECT_CALL(local_, SendChangesToSyncServer(_)).Times(0);
- local_.AutofillMultipleChanged();
+ local_.AutofillMultipleChangedBySync();
}
// Verify that the merge logic keeps the best data on a field by field basis.
@@ -1337,8 +1337,8 @@ TEST_F(AutofillWalletMetadataSyncableServiceTest,
// Make the backend broadcast back the notifications it receives
ON_CALL(backend_, NotifyOfMultipleAutofillChanges())
.WillByDefault(
- DoAll(Invoke(&local_, &MockService::AutofillMultipleChanged),
- Invoke(&remote_, &MockService::AutofillMultipleChanged)));
+ DoAll(Invoke(&local_, &MockService::AutofillMultipleChangedBySync),
+ Invoke(&remote_, &MockService::AutofillMultipleChangedBySync)));
// Get initial data from |remote_| into |local_|.
local_.UpdateAddressStats(BuildAddress(kAddr1, 2, 2, true));
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 a3a4494ddb1..aa51b2fbae7 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
@@ -198,7 +198,9 @@ base::Optional<syncer::ModelError> AutofillWalletSyncBridge::MergeSyncData(
return error;
}
- SetSyncData(entity_data);
+ // We want to notify the metadata bridge about all changes so that the
+ // metadata bridge can track changes in the data bridge and react accordingly.
+ SetSyncData(entity_data, /*notify_metadata_bridge=*/true);
// After the first sync, we are sure that initial sync is done.
if (!initial_sync_done_) {
@@ -277,7 +279,10 @@ void AutofillWalletSyncBridge::ApplyStopSyncChanges(
SyncWalletDataRecordClearedEntitiesCount(count);
}
- SetSyncData(syncer::EntityChangeList());
+ // Do not notify the metadata bridge because we do not want to upstream the
+ // deletions. The metadata bridge deletes its data independently when sync
+ // gets stopped.
+ SetSyncData(syncer::EntityChangeList(), /*notify_metadata_bridge=*/false);
initial_sync_done_ = false;
}
@@ -323,7 +328,8 @@ void AutofillWalletSyncBridge::GetAllDataImpl(DataCallback callback,
}
void AutofillWalletSyncBridge::SetSyncData(
- const syncer::EntityChangeList& entity_data) {
+ const syncer::EntityChangeList& entity_data,
+ bool notify_metadata_bridge) {
bool wallet_data_changed = false;
// Extract the Autofill types from the sync |entity_data|.
@@ -336,10 +342,10 @@ void AutofillWalletSyncBridge::SetSyncData(
bool should_log_diff;
wallet_data_changed |=
SetPaymentsCustomerData(std::move(customer_data), &should_log_diff);
- wallet_data_changed |=
- SetWalletCards(std::move(wallet_cards), should_log_diff);
- wallet_data_changed |=
- SetWalletAddresses(std::move(wallet_addresses), should_log_diff);
+ wallet_data_changed |= SetWalletCards(
+ std::move(wallet_cards), should_log_diff, notify_metadata_bridge);
+ wallet_data_changed |= SetWalletAddresses(
+ std::move(wallet_addresses), should_log_diff, notify_metadata_bridge);
// Commit the transaction to make sure the data and the metadata with the
// new progress marker is written down (especially on Android where we
@@ -354,7 +360,8 @@ void AutofillWalletSyncBridge::SetSyncData(
bool AutofillWalletSyncBridge::SetWalletCards(
std::vector<CreditCard> wallet_cards,
- bool log_diff) {
+ bool log_diff,
+ bool notify_metadata_bridge) {
// Users can set billing address of the server credit card locally, but that
// information does not propagate to either Chrome Sync or Google Payments
// server. To preserve user's preferred billing address and most recent use
@@ -386,8 +393,11 @@ bool AutofillWalletSyncBridge::SetWalletCards(
} else {
table->SetServerCreditCards(wallet_cards);
}
- for (const CreditCardChange& change : diff.changes)
- web_data_backend_->NotifyOfCreditCardChanged(change);
+ if (notify_metadata_bridge) {
+ for (const CreditCardChange& change : diff.changes) {
+ web_data_backend_->NotifyOfCreditCardChanged(change);
+ }
+ }
return true;
}
return false;
@@ -395,7 +405,16 @@ bool AutofillWalletSyncBridge::SetWalletCards(
bool AutofillWalletSyncBridge::SetWalletAddresses(
std::vector<AutofillProfile> wallet_addresses,
- bool log_diff) {
+ bool log_diff,
+ bool notify_metadata_bridge) {
+ // We do not have to CopyRelevantWalletMetadataFromDisk() because we will
+ // never overwrite the same entity with different data (server_id is generated
+ // based on content so addresses have the same server_id iff they have the
+ // same content). For that reason it is impossible to issue a DELETE and ADD
+ // for the same entity just because some of its fields got changed. As a
+ // result, we do not need to care to have up-to-date use stats for cards
+ // because we never notify on an existing one.
+
// In the common case, the database won't have changed. Committing an update
// to the database will require at least one DB page write and will schedule
// a fsync. To avoid this I/O, it should be more efficient to do a read and
@@ -422,8 +441,11 @@ bool AutofillWalletSyncBridge::SetWalletAddresses(
} else {
table->SetServerProfiles(wallet_addresses);
}
- for (const AutofillProfileChange& change : diff.changes)
- web_data_backend_->NotifyOfAutofillProfileChanged(change);
+ if (notify_metadata_bridge) {
+ for (const AutofillProfileChange& change : diff.changes) {
+ web_data_backend_->NotifyOfAutofillProfileChanged(change);
+ }
+ }
return true;
}
return false;
@@ -491,8 +513,11 @@ AutofillWalletSyncBridge::ComputeAutofillWalletDiff(
std::sort(old_ptrs.begin(), old_ptrs.end(), compare);
std::sort(new_ptrs.begin(), new_ptrs.end(), compare);
- // Walk over both of them and count added/removed elements.
AutofillWalletDiff<Item> result;
+ // We collect ADD changes separately to ensure proper order.
+ std::vector<AutofillDataModelChange<Item>> add_changes;
+
+ // Walk over both of them and count added/removed elements.
auto old_it = old_ptrs.begin();
auto new_it = new_ptrs.begin();
while (old_it != old_ptrs.end() || new_it != new_ptrs.end()) {
@@ -508,19 +533,25 @@ AutofillWalletSyncBridge::ComputeAutofillWalletDiff(
if (cmp < 0) {
++result.items_removed;
result.changes.emplace_back(AutofillDataModelChange<Item>::REMOVE,
- (*old_it)->server_id(), nullptr);
+ (*old_it)->server_id(), *old_it);
++old_it;
} else if (cmp == 0) {
++old_it;
++new_it;
} else {
++result.items_added;
- result.changes.emplace_back(AutofillDataModelChange<Item>::ADD,
- (*new_it)->server_id(), *new_it);
+ add_changes.emplace_back(AutofillDataModelChange<Item>::ADD,
+ (*new_it)->server_id(), *new_it);
++new_it;
}
}
+ // Append ADD changes to make sure they all come after all REMOVE changes.
+ // Since we CopyRelevantWalletMetadataFromDisk(), the ADD contains all current
+ // metadata if we happen to REMOVE and ADD the same entity.
+ result.changes.insert(result.changes.end(), add_changes.begin(),
+ add_changes.end());
+
DCHECK_EQ(old_data.size() + result.items_added - result.items_removed,
new_data.size());
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 3f91a3c6276..3fbf638ba0f 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
@@ -88,8 +88,10 @@ class AutofillWalletSyncBridge : public base::SupportsUserData::Data,
void GetAllDataImpl(DataCallback callback, bool enforce_utf8);
// Sets the wallet data from |entity_data| to this client and records metrics
- // about added/deleted data.
- void SetSyncData(const syncer::EntityChangeList& entity_data);
+ // about added/deleted data. If |notify_metadata_bridge|, it also notifies
+ // the metadata sync bridge about individual changes.
+ void SetSyncData(const syncer::EntityChangeList& entity_data,
+ bool notify_metadata_bridge);
// Sets |customer_data| to this client and returns whether any change has been
// applied (i.e., whether |customer_data| was different from local data) and
@@ -100,14 +102,21 @@ class AutofillWalletSyncBridge : public base::SupportsUserData::Data,
// Sets |wallet_cards| to this client, records metrics about added/deleted
// data (if |log_diff| is true) and returns whether any change has been
- // applied (i.e., whether |wallet_cards| was different from local data).
- bool SetWalletCards(std::vector<CreditCard> wallet_cards, bool log_diff);
+ // applied (i.e., whether |wallet_cards| was different from local data). If
+ // |notify_metadata_bridge|, it also notifies via WebDataBackend about any
+ // individual entity changes.
+ bool SetWalletCards(std::vector<CreditCard> wallet_cards,
+ bool log_diff,
+ bool notify_metadata_bridge);
// Sets |wallet_addresses| to this client, records metrics about added/deleted
// data (if |log_diff| is true) and returns whether any change has been
// applied (i.e., whether |wallet_addresses| was different from local data).
+ // If |notify_metadata_bridge|, it also notifies via WebDataBackend about any
+ // individual entity changes.
bool SetWalletAddresses(std::vector<AutofillProfile> wallet_addresses,
- bool log_diff);
+ bool log_diff,
+ bool notify_metadata_bridge);
// Computes a "diff" (items added, items removed) of two vectors of items,
// which should be either CreditCard or AutofillProfile. This is used for
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 9549f984cc4..c595c29bfbc 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
@@ -57,7 +57,6 @@ using sync_pb::ModelTypeState;
using syncer::DataBatch;
using syncer::EntityChange;
using syncer::EntityData;
-using syncer::EntityDataPtr;
using syncer::HasInitialSyncDone;
using syncer::KeyAndData;
using syncer::MockModelTypeChangeProcessor;
@@ -276,7 +275,7 @@ class AutofillWalletSyncBridgeTest : public UssSwitchToggler,
for (const AutofillWalletSpecifics& specifics : remote_data) {
initial_updates.push_back(SpecificsToUpdateResponse(specifics));
}
- real_processor_->OnUpdateReceived(state, initial_updates);
+ real_processor_->OnUpdateReceived(state, std::move(initial_updates));
}
void ExpectAddressesDiffInHistograms(int added, int removed) {
@@ -329,11 +328,12 @@ class AutofillWalletSyncBridgeTest : public UssSwitchToggler,
EXPECT_EQ(addresses_count, addresses_metadata.size());
}
- EntityData SpecificsToEntity(const AutofillWalletSpecifics& specifics) {
- EntityData data;
- *data.specifics.mutable_autofill_wallet() = specifics;
- data.client_tag_hash = syncer::GenerateSyncableHash(
- syncer::AUTOFILL_WALLET_DATA, bridge()->GetClientTag(data));
+ std::unique_ptr<EntityData> SpecificsToEntity(
+ const AutofillWalletSpecifics& specifics) {
+ auto data = std::make_unique<EntityData>();
+ *data->specifics.mutable_autofill_wallet() = specifics;
+ data->client_tag_hash = syncer::GenerateSyncableHash(
+ syncer::AUTOFILL_WALLET_DATA, bridge()->GetClientTag(*data));
return data;
}
@@ -350,10 +350,10 @@ class AutofillWalletSyncBridgeTest : public UssSwitchToggler,
return data;
}
- syncer::UpdateResponseData SpecificsToUpdateResponse(
+ std::unique_ptr<syncer::UpdateResponseData> SpecificsToUpdateResponse(
const AutofillWalletSpecifics& specifics) {
- syncer::UpdateResponseData data;
- data.entity = SpecificsToEntity(specifics).PassToPtr();
+ auto data = std::make_unique<syncer::UpdateResponseData>();
+ data->entity = SpecificsToEntity(specifics);
return data;
}
@@ -392,14 +392,14 @@ class AutofillWalletSyncBridgeTest : public UssSwitchToggler,
TEST_P(AutofillWalletSyncBridgeTest, GetClientTagForAddress) {
AutofillWalletSpecifics specifics =
CreateAutofillWalletSpecificsForAddress(kAddr1SpecificsId);
- EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
+ EXPECT_EQ(bridge()->GetClientTag(*SpecificsToEntity(specifics)),
kAddr1SyncTag);
}
TEST_P(AutofillWalletSyncBridgeTest, GetClientTagForCard) {
AutofillWalletSpecifics specifics =
CreateAutofillWalletSpecificsForCard(kCard1SpecificsId);
- EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
+ EXPECT_EQ(bridge()->GetClientTag(*SpecificsToEntity(specifics)),
kCard1SyncTag);
}
@@ -407,7 +407,7 @@ TEST_P(AutofillWalletSyncBridgeTest, GetClientTagForCustomerData) {
AutofillWalletSpecifics specifics =
CreateAutofillWalletSpecificsForPaymentsCustomerData(
kCustomerDataSyncTag);
- EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
+ EXPECT_EQ(bridge()->GetClientTag(*SpecificsToEntity(specifics)),
kCustomerDataSyncTag);
}
@@ -415,21 +415,21 @@ TEST_P(AutofillWalletSyncBridgeTest, GetClientTagForCustomerData) {
TEST_P(AutofillWalletSyncBridgeTest, GetStorageKeyForAddress) {
AutofillWalletSpecifics specifics1 =
CreateAutofillWalletSpecificsForAddress(kAddr1SpecificsId);
- EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics1)),
+ EXPECT_EQ(bridge()->GetStorageKey(*SpecificsToEntity(specifics1)),
kAddr1SpecificsId);
}
TEST_P(AutofillWalletSyncBridgeTest, GetStorageKeyForCard) {
AutofillWalletSpecifics specifics2 =
CreateAutofillWalletSpecificsForCard(kCard1SpecificsId);
- EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics2)),
+ EXPECT_EQ(bridge()->GetStorageKey(*SpecificsToEntity(specifics2)),
kCard1SpecificsId);
}
TEST_P(AutofillWalletSyncBridgeTest, GetStorageKeyForCustomerData) {
AutofillWalletSpecifics specifics3 =
CreateAutofillWalletSpecificsForPaymentsCustomerData(kCustomerDataId);
- EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics3)),
+ EXPECT_EQ(bridge()->GetStorageKey(*SpecificsToEntity(specifics3)),
kCustomerDataId);
}
@@ -826,10 +826,9 @@ TEST_P(AutofillWalletSyncBridgeTest, ApplyStopSyncChanges_ClearAllData) {
EXPECT_CALL(*backend(), CommitChanges());
EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges());
- EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(
- RemoveChange(local_profile.server_id())));
- EXPECT_CALL(*backend(),
- NotifyOfCreditCardChanged(RemoveChange(local_card.server_id())));
+ EXPECT_CALL(*backend(), NotifyOfAutofillProfileChanged(_)).Times(0);
+ EXPECT_CALL(*backend(), NotifyOfCreditCardChanged(_)).Times(0);
+
// Passing in a non-null metadata change list indicates to the bridge that
// sync is stopping because it was disabled.
bridge()->ApplyStopSyncChanges(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc b/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
index 3cc21a09948..86f17c89f42 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
@@ -206,6 +206,12 @@ AutofillWalletSyncableService::AutofillWalletSyncableService(
AutofillWalletSyncableService::~AutofillWalletSyncableService() {}
+void AutofillWalletSyncableService::WaitUntilReadyToSync(
+ base::OnceClosure done) {
+ // Not used in the legacy directory-based architecture.
+ NOTREACHED();
+}
+
syncer::SyncMergeResult AutofillWalletSyncableService::MergeDataAndStartSyncing(
syncer::ModelType type,
const syncer::SyncDataList& initial_sync_data,
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h b/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
index e8c130d73ca..9d3ff000790 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
@@ -35,6 +35,7 @@ class AutofillWalletSyncableService
~AutofillWalletSyncableService() override;
// syncer::SyncableService implementation.
+ void WaitUntilReadyToSync(base::OnceClosure done) override;
syncer::SyncMergeResult MergeDataAndStartSyncing(
syncer::ModelType type,
const syncer::SyncDataList& initial_sync_data,
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata.h
deleted file mode 100644
index 3ae94e14cae..00000000000
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata.h
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2013 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_WEBDATA_AUTOFILL_WEBDATA_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WEBDATA_H_
-
-#include <string>
-#include <vector>
-
-#include "base/strings/string16.h"
-#include "components/webdata/common/web_data_service_base.h"
-
-namespace base {
-
-class Time;
-
-} // namespace base
-
-class WebDataServiceConsumer;
-
-namespace autofill {
-
-class AutofillEntry;
-class AutofillProfile;
-class CreditCard;
-struct FormFieldData;
-
-// Pure virtual interface for retrieving Autofill data. API users
-// should use AutofillWebDataService.
-class AutofillWebData {
- public:
- virtual ~AutofillWebData() {}
-
- // Schedules a task to add form fields to the web database.
- virtual void AddFormFields(
- const std::vector<FormFieldData>& fields) = 0;
-
- // Initiates the request for a vector of values which have been entered in
- // form input fields named |name|. The method OnWebDataServiceRequestDone of
- // |consumer| gets called back when the request is finished, with the vector
- // included in the argument |result|.
- virtual WebDataServiceBase::Handle GetFormValuesForElementName(
- const base::string16& name,
- const base::string16& prefix,
- int limit,
- WebDataServiceConsumer* consumer) = 0;
-
- // Removes form elements recorded for Autocomplete from the database.
- virtual void RemoveFormElementsAddedBetween(
- const base::Time& delete_begin, const base::Time& delete_end) = 0;
-
- virtual void RemoveFormValueForElementName(const base::string16& name,
- const base::string16& value) = 0;
-
- // Schedules a task to add an Autofill profile to the web database.
- virtual void AddAutofillProfile(const AutofillProfile& profile) = 0;
-
- // Schedules a task to update an Autofill profile in the web database.
- virtual void UpdateAutofillProfile(const AutofillProfile& profile) = 0;
-
- // Schedules a task to remove an Autofill profile from the web database.
- // |guid| is the identifier of the profile to remove.
- virtual void RemoveAutofillProfile(const std::string& guid) = 0;
-
- // Initiates the request for local/server Autofill profiles. The method
- // OnWebDataServiceRequestDone of |consumer| gets called when the request is
- // finished, with the profiles included in the argument |result|. The
- // consumer owns the profiles.
- virtual WebDataServiceBase::Handle GetAutofillProfiles(
- WebDataServiceConsumer* consumer) = 0;
- virtual WebDataServiceBase::Handle GetServerProfiles(
- WebDataServiceConsumer* consumer) = 0;
-
- // Schedules a task to count the number of unique autofill values contained
- // in the time interval [|begin|, |end|). |begin| and |end| can be null
- // to indicate no time limitation.
- virtual WebDataServiceBase::Handle GetCountOfValuesContainedBetween(
- const base::Time& begin,
- const base::Time& end,
- WebDataServiceConsumer* consumer) = 0;
-
- // Schedules a task to update autofill entries in the web database.
- virtual void UpdateAutofillEntries(
- const std::vector<AutofillEntry>& autofill_entries) = 0;
-
- // Schedules a task to add credit card to the web database.
- virtual void AddCreditCard(const CreditCard& credit_card) = 0;
-
- // Schedules a task to update credit card in the web database.
- virtual void UpdateCreditCard(const CreditCard& credit_card) = 0;
-
- // Schedules a task to remove a credit card from the web database.
- // |guid| is identifier of the credit card to remove.
- virtual void RemoveCreditCard(const std::string& guid) = 0;
-
- // Schedules a task to add a full server credit card to the web database.
- virtual void AddFullServerCreditCard(const CreditCard& credit_card) = 0;
-
- // Initiates the request for local/server credit cards. The method
- // OnWebDataServiceRequestDone of |consumer| gets called when the request is
- // finished, with the credit cards included in the argument |result|. The
- // consumer owns the credit cards.
- virtual WebDataServiceBase::Handle GetCreditCards(
- WebDataServiceConsumer* consumer) = 0;
- virtual WebDataServiceBase::Handle GetServerCreditCards(
- WebDataServiceConsumer* consumer) = 0;
-
- // Toggles the record for a server credit card between masked (only last 4
- // digits) and full (all digits).
- virtual void UnmaskServerCreditCard(const CreditCard& credit_card,
- const base::string16& full_number) = 0;
- virtual void MaskServerCreditCard(const std::string& id) = 0;
-
- // Initiates the request for Payments customer data. The method
- // OnWebDataServiceRequestDone of |consumer| gets called when the request is
- // finished, with the customer data included in the argument |result|. The
- // consumer owns the data.
- virtual WebDataServiceBase::Handle GetPaymentsCustomerData(
- WebDataServiceConsumer* consumer) = 0;
-
- // Updates the metadata for a server card (masked or not).
- virtual void UpdateServerCardMetadata(const CreditCard& credit_card) = 0;
-
- // Updates the metadata for a server address.
- virtual void UpdateServerAddressMetadata(const AutofillProfile& profile) = 0;
-
- // Removes Autofill records from the database.
- virtual void RemoveAutofillDataModifiedBetween(
- const base::Time& delete_begin, const base::Time& delete_end) = 0;
-
- // Removes origin URLs associated with Autofill profiles and credit cards from
- // the database.
- virtual void RemoveOriginURLsModifiedBetween(
- const base::Time& delete_begin, const base::Time& delete_end) = 0;
-
- // Removes the orphan rows in the autofill_profile_names,
- // autofill_profile_emails and autofill_profile_phones tables.
- virtual void RemoveOrphanAutofillTableRows() = 0;
-};
-
-} // namespace autofill
-
-#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WEBDATA_H_
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 aa37b89bc4d..57be6d9e2d1 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend.h
@@ -59,6 +59,12 @@ class AutofillWebDataBackend {
// sequence notifications are asynchronous.
virtual void NotifyOfMultipleAutofillChanges() = 0;
+ // Notifies listeners on the UI sequence that conversion of server profiles
+ // into local profiles is completed.
+ // NOTE: This method is intended to be called from the DB sequence. The UI
+ // sequence notifications are asynchronous.
+ virtual void NotifyOfAddressConversionCompleted() = 0;
+
// Notifies listeners on the UI sequence that sync has started for
// |model_type|.
// 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 d7cb6af4768..3d1c7083aac 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
@@ -15,6 +15,7 @@
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_entry.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_backend_util.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
#include "components/autofill/core/common/form_field_data.h"
@@ -36,12 +37,15 @@ AutofillWebDataBackendImpl::AutofillWebDataBackendImpl(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> db_task_runner,
const base::Closure& on_changed_callback,
+ const base::Closure& on_address_conversion_completed_callback,
const base::Callback<void(syncer::ModelType)>& on_sync_started_callback)
: base::RefCountedDeleteOnSequence<AutofillWebDataBackendImpl>(
std::move(db_task_runner)),
ui_task_runner_(ui_task_runner),
web_database_backend_(web_database_backend),
on_changed_callback_(on_changed_callback),
+ on_address_conversion_completed_callback_(
+ on_address_conversion_completed_callback),
on_sync_started_callback_(on_sync_started_callback) {}
void AutofillWebDataBackendImpl::AddObserver(
@@ -121,12 +125,20 @@ void AutofillWebDataBackendImpl::NotifyOfMultipleAutofillChanges() {
// DB sequence notification.
for (auto& db_observer : db_observer_list_)
- db_observer.AutofillMultipleChanged();
+ db_observer.AutofillMultipleChangedBySync();
// UI sequence notification.
ui_task_runner_->PostTask(FROM_HERE, on_changed_callback_);
}
+void AutofillWebDataBackendImpl::NotifyOfAddressConversionCompleted() {
+ DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
+
+ // UI sequence notification.
+ ui_task_runner_->PostTask(FROM_HERE,
+ on_address_conversion_completed_callback_);
+}
+
void AutofillWebDataBackendImpl::NotifyThatSyncHasStarted(
syncer::ModelType model_type) {
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
@@ -294,15 +306,17 @@ WebDatabase::State AutofillWebDataBackendImpl::RemoveAutofillProfile(
}
// Send GUID-based notification.
- AutofillProfileChange change(AutofillProfileChange::REMOVE, guid, nullptr);
+ AutofillProfileChange change(AutofillProfileChange::REMOVE, guid,
+ profile.get());
for (auto& db_observer : db_observer_list_)
db_observer.AutofillProfileChanged(change);
if (!on_autofill_profile_changed_cb_.is_null()) {
ui_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(on_autofill_profile_changed_cb_,
- AutofillProfileDeepChange(
- AutofillProfileChange::REMOVE, guid)));
+ FROM_HERE,
+ base::BindOnce(on_autofill_profile_changed_cb_,
+ AutofillProfileDeepChange(AutofillProfileChange::REMOVE,
+ *profile.get())));
}
return WebDatabase::COMMIT_NEEDED;
@@ -328,6 +342,16 @@ std::unique_ptr<WDTypedResult> AutofillWebDataBackendImpl::GetServerProfiles(
AUTOFILL_PROFILES_RESULT, std::move(profiles)));
}
+WebDatabase::State
+AutofillWebDataBackendImpl::ConvertWalletAddressesAndUpdateWalletCards(
+ const std::string& app_locale,
+ const std::string& primary_account_email,
+ WebDatabase* db) {
+ DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
+ return util::ConvertWalletAddressesAndUpdateWalletCards(
+ app_locale, primary_account_email, this, db);
+}
+
std::unique_ptr<WDTypedResult>
AutofillWebDataBackendImpl::GetCountOfValuesContainedBetween(
const base::Time& begin,
@@ -391,6 +415,13 @@ WebDatabase::State AutofillWebDataBackendImpl::UpdateCreditCard(
WebDatabase::State AutofillWebDataBackendImpl::RemoveCreditCard(
const std::string& guid, WebDatabase* db) {
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
+ std::unique_ptr<CreditCard> card =
+ AutofillTable::FromWebDatabase(db)->GetCreditCard(guid);
+ if (!card) {
+ NOTREACHED();
+ return WebDatabase::COMMIT_NOT_NEEDED;
+ }
+
if (!AutofillTable::FromWebDatabase(db)->RemoveCreditCard(guid)) {
NOTREACHED();
return WebDatabase::COMMIT_NOT_NEEDED;
@@ -398,7 +429,7 @@ WebDatabase::State AutofillWebDataBackendImpl::RemoveCreditCard(
for (auto& db_observer : db_observer_list_) {
db_observer.CreditCardChanged(
- CreditCardChange(CreditCardChange::REMOVE, guid, nullptr));
+ CreditCardChange(CreditCardChange::REMOVE, guid, card.get()));
}
return WebDatabase::COMMIT_NEEDED;
}
@@ -530,23 +561,20 @@ WebDatabase::State
const base::Time& delete_end,
WebDatabase* db) {
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
- std::vector<std::string> profile_guids;
- std::vector<std::string> credit_card_guids;
+ std::vector<std::unique_ptr<AutofillProfile>> profiles;
+ std::vector<std::unique_ptr<CreditCard>> credit_cards;
if (AutofillTable::FromWebDatabase(db)->RemoveAutofillDataModifiedBetween(
- delete_begin,
- delete_end,
- &profile_guids,
- &credit_card_guids)) {
- for (const std::string& guid : profile_guids) {
+ delete_begin, delete_end, &profiles, &credit_cards)) {
+ for (const std::unique_ptr<AutofillProfile>& profile : profiles) {
for (auto& db_observer : db_observer_list_) {
db_observer.AutofillProfileChanged(AutofillProfileChange(
- AutofillProfileChange::REMOVE, guid, nullptr));
+ AutofillProfileChange::REMOVE, profile->guid(), profile.get()));
}
}
- for (const std::string& guid : credit_card_guids) {
+ for (const std::unique_ptr<CreditCard>& credit_card : credit_cards) {
for (auto& db_observer : db_observer_list_) {
- db_observer.CreditCardChanged(
- CreditCardChange(CreditCardChange::REMOVE, guid, nullptr));
+ db_observer.CreditCardChanged(CreditCardChange(
+ CreditCardChange::REMOVE, credit_card->guid(), credit_card.get()));
}
}
// Note: It is the caller's responsibility to post notifications for any
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 b508bda93b1..ebd32175352 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
@@ -12,7 +12,6 @@
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/observer_list.h"
#include "base/supports_user_data.h"
-#include "components/autofill/core/browser/webdata/autofill_webdata.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/webdata/common/web_data_results.h"
@@ -53,6 +52,7 @@ class AutofillWebDataBackendImpl
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> db_task_runner,
const base::Closure& on_changed_callback,
+ const base::Closure& on_address_conversion_completed_callback,
const base::Callback<void(syncer::ModelType)>& on_sync_started_callback);
void SetAutofillProfileChangedCallback(
@@ -69,6 +69,7 @@ class AutofillWebDataBackendImpl
const AutofillProfileChange& change) override;
void NotifyOfCreditCardChanged(const CreditCardChange& change) override;
void NotifyOfMultipleAutofillChanges() override;
+ void NotifyOfAddressConversionCompleted() override;
void NotifyThatSyncHasStarted(syncer::ModelType model_type) override;
void CommitChanges() override;
@@ -134,6 +135,15 @@ class AutofillWebDataBackendImpl
std::unique_ptr<WDTypedResult> GetAutofillProfiles(WebDatabase* db);
std::unique_ptr<WDTypedResult> GetServerProfiles(WebDatabase* db);
+ // Converts server profiles to local profiles, comparing profiles using
+ // |app_locale| and filling in |primary_account_email| into newly converted
+ // profiles. The task only converts profiles that have not been converted
+ // before.
+ WebDatabase::State ConvertWalletAddressesAndUpdateWalletCards(
+ const std::string& app_locale,
+ const std::string& primary_account_email,
+ WebDatabase* db);
+
// Returns the number of values such that all for autofill entries with that
// value, the interval between creation date and last usage is entirely
// contained between [|begin|, |end|).
@@ -246,6 +256,7 @@ class AutofillWebDataBackendImpl
scoped_refptr<WebDatabaseBackend> web_database_backend_;
base::Closure on_changed_callback_;
+ base::Closure on_address_conversion_completed_callback_;
base::Callback<void(syncer::ModelType)> on_sync_started_callback_;
base::RepeatingCallback<void(const AutofillProfileDeepChange&)>
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc
new file mode 100644
index 00000000000..0af8ed2b2cc
--- /dev/null
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.cc
@@ -0,0 +1,264 @@
+// 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/webdata/autofill_webdata_backend_util.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_country.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_profile_comparator.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/payments/payments_customer_data.h"
+#include "components/autofill/core/browser/webdata/autofill_change.h"
+#include "components/autofill/core/browser/webdata/autofill_entry.h"
+#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h"
+#include "components/autofill/core/common/autofill_clock.h"
+
+namespace autofill {
+
+namespace util {
+
+namespace {
+
+// The length of a local profile GUID.
+const int LOCAL_GUID_LENGTH = 36;
+
+// TODO(crbug.com/687975): Reuse MergeProfile in this function.
+// static
+std::string MergeServerAddressesIntoProfiles(
+ const AutofillProfile& server_address,
+ std::vector<std::unique_ptr<AutofillProfile>>* existing_profiles,
+ const std::string& app_locale,
+ const std::string& primary_account_email,
+ AutofillWebDataBackendImpl* backend,
+ WebDatabase* db) {
+ // If there is already a local profile that is very similar, merge in any
+ // missing values. Only merge with the first match.
+ AutofillProfileComparator comparator(app_locale);
+ for (auto& local_profile : *existing_profiles) {
+ if (comparator.AreMergeable(server_address, *local_profile) &&
+ local_profile->SaveAdditionalInfo(server_address, app_locale)) {
+ local_profile->set_modification_date(AutofillClock::Now());
+ backend->UpdateAutofillProfile(*local_profile, db);
+ AutofillMetrics::LogWalletAddressConversionType(
+ AutofillMetrics::CONVERTED_ADDRESS_MERGED);
+ return local_profile->guid();
+ }
+ }
+
+ // If the server address was not merged with a local profile, add it to the
+ // list.
+ existing_profiles->push_back(
+ std::make_unique<AutofillProfile>(server_address));
+ // Set the profile as being local.
+ existing_profiles->back()->set_record_type(AutofillProfile::LOCAL_PROFILE);
+ existing_profiles->back()->set_modification_date(AutofillClock::Now());
+
+ // Wallet addresses don't have an email address, use the one from the
+ // currently signed-in account.
+ base::string16 email = base::UTF8ToUTF16(primary_account_email);
+ if (!email.empty())
+ existing_profiles->back()->SetRawInfo(EMAIL_ADDRESS, email);
+
+ backend->AddAutofillProfile(*existing_profiles->back(), db);
+ AutofillMetrics::LogWalletAddressConversionType(
+ AutofillMetrics::CONVERTED_ADDRESS_ADDED);
+
+ return existing_profiles->back()->guid();
+}
+
+bool ConvertWalletAddressesToLocalProfiles(
+ const std::string& app_locale,
+ const std::string& primary_account_email,
+ const std::vector<std::unique_ptr<AutofillProfile>>& server_profiles,
+ std::vector<std::unique_ptr<AutofillProfile>>* local_profiles,
+ std::unordered_map<std::string, AutofillProfile*>* server_id_profiles_map,
+ std::unordered_map<std::string, std::string>* guids_merge_map,
+ AutofillWebDataBackendImpl* backend,
+ WebDatabase* db) {
+ bool has_converted_addresses = false;
+ for (const std::unique_ptr<AutofillProfile>& wallet_address :
+ server_profiles) {
+ // Add the profile to the map.
+ server_id_profiles_map->emplace(wallet_address->server_id(),
+ wallet_address.get());
+
+ // If the address has not been converted yet, convert it.
+ 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.
+ std::string address_guid = MergeServerAddressesIntoProfiles(
+ *wallet_address, local_profiles, app_locale, primary_account_email,
+ backend, db);
+
+ // Update the map to transfer the billing address relationship from the
+ // server address to the converted/merged local profile.
+ guids_merge_map->emplace(wallet_address->server_id(), address_guid);
+
+ // Update the wallet addresses metadata to record the conversion.
+ AutofillProfile updated_address = *wallet_address;
+ updated_address.set_has_converted(true);
+ backend->UpdateServerAddressMetadata(updated_address, db);
+
+ has_converted_addresses = true;
+ }
+ }
+
+ return has_converted_addresses;
+}
+
+bool UpdateWalletCardsAlreadyConvertedBillingAddresses(
+ const std::vector<std::unique_ptr<AutofillProfile>>& local_profiles,
+ const std::vector<std::unique_ptr<CreditCard>>& server_cards,
+ const std::unordered_map<std::string, AutofillProfile*>&
+ server_id_profiles_map,
+ const std::string& app_locale,
+ std::unordered_map<std::string, std::string>* guids_merge_map) {
+ // Look for server cards that still refer to server addresses but for which
+ // there is no mapping. This can happen if it's a new card for which the
+ // billing address has already been converted. This should be a no-op for most
+ // situations. Otherwise, it should affect only one Wallet card, sinces users
+ // do not add a lot of credit cards.
+ AutofillProfileComparator comparator(app_locale);
+ bool should_update_cards = false;
+ for (const std::unique_ptr<CreditCard>& wallet_card : server_cards) {
+ std::string billing_address_id = wallet_card->billing_address_id();
+
+ // If billing address refers to a server id and that id is not a key in the
+ // |guids_merge_map|, it means that the card is new but the address was
+ // already converted. Look for the matching converted profile.
+ if (!billing_address_id.empty() &&
+ billing_address_id.length() != LOCAL_GUID_LENGTH &&
+ guids_merge_map->find(billing_address_id) == guids_merge_map->end()) {
+ // Get the profile.
+ auto it = server_id_profiles_map.find(billing_address_id);
+ if (it != server_id_profiles_map.end()) {
+ const AutofillProfile* billing_address = it->second;
+
+ // Look for a matching local profile (DO NOT MERGE).
+ for (const auto& local_profile : local_profiles) {
+ if (comparator.AreMergeable(*billing_address, *local_profile)) {
+ // The Wallet address matches this local profile. Add this to the
+ // merge mapping.
+ guids_merge_map->emplace(billing_address_id, local_profile->guid());
+ should_update_cards = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return should_update_cards;
+}
+
+// TODO(crbug.com/911133): This function implements the same logic as the
+// function with the same name in PDM. Move ApplyDedupingRoutine to the backend
+// thread as well and thus get rid of the code duplicity.
+void UpdateCardsBillingAddressReference(
+ const std::unordered_map<std::string, std::string>& guids_merge_map,
+ std::vector<std::unique_ptr<CreditCard>> credit_cards,
+ AutofillWebDataBackendImpl* backend,
+ WebDatabase* db) {
+ /* Here is an example of what the graph might look like.
+
+ A -> B
+ \
+ -> E
+ /
+ C -> D
+ */
+
+ for (std::unique_ptr<CreditCard>& credit_card : credit_cards) {
+ // If the credit card is not associated with a billing address, skip it.
+ if (credit_card->billing_address_id().empty())
+ break;
+
+ // If the billing address profile associated with the card has been merged,
+ // replace it by the id of the profile in which it was merged. Repeat the
+ // process until the billing address has not been merged into another one.
+ bool was_modified = false;
+ auto it = guids_merge_map.find(credit_card->billing_address_id());
+ while (it != guids_merge_map.end()) {
+ was_modified = true;
+ credit_card->set_billing_address_id(it->second);
+ it = guids_merge_map.find(credit_card->billing_address_id());
+ }
+
+ if (was_modified) {
+ if (credit_card->record_type() == CreditCard::LOCAL_CARD) {
+ backend->UpdateCreditCard(*credit_card, db);
+ } else {
+ backend->UpdateServerCardMetadata(*credit_card, db);
+ }
+ }
+ }
+}
+
+} // namespace
+
+WebDatabase::State ConvertWalletAddressesAndUpdateWalletCards(
+ const std::string& app_locale,
+ const std::string& primary_account_email,
+ AutofillWebDataBackendImpl* backend,
+ WebDatabase* db) {
+ AutofillTable* table = AutofillTable::FromWebDatabase(db);
+
+ // Get a copy of local profiles.
+ std::vector<std::unique_ptr<AutofillProfile>> local_profiles;
+ std::vector<std::unique_ptr<AutofillProfile>> server_profiles;
+ std::vector<std::unique_ptr<CreditCard>> server_cards;
+ if (!table->GetAutofillProfiles(&local_profiles) ||
+ !table->GetServerProfiles(&server_profiles) ||
+ !table->GetServerCreditCards(&server_cards)) {
+ return WebDatabase::COMMIT_NOT_NEEDED;
+ }
+
+ // Since we are already iterating on all the server profiles to convert Wallet
+ // addresses and we will need to access them by guid later to update the
+ // Wallet cards, create a map here.
+ std::unordered_map<std::string, AutofillProfile*> server_id_profiles_map;
+
+ // Create the map used to update credit card's billing addresses after the
+ // conversion/merge.
+ std::unordered_map<std::string, std::string> guids_merge_map;
+
+ bool has_converted_addresses = ConvertWalletAddressesToLocalProfiles(
+ app_locale, primary_account_email, server_profiles, &local_profiles,
+ &server_id_profiles_map, &guids_merge_map, backend, db);
+ bool should_update_cards = UpdateWalletCardsAlreadyConvertedBillingAddresses(
+ local_profiles, server_cards, server_id_profiles_map, app_locale,
+ &guids_merge_map);
+
+ if (should_update_cards || has_converted_addresses) {
+ std::vector<std::unique_ptr<CreditCard>> all_cards;
+ if (!table->GetCreditCards(&all_cards)) {
+ return WebDatabase::COMMIT_NEEDED;
+ }
+ for (std::unique_ptr<CreditCard>& server_card : server_cards) {
+ all_cards.push_back(std::move(server_card));
+ }
+
+ // Update the credit cards billing address relationship.
+ UpdateCardsBillingAddressReference(guids_merge_map, std::move(all_cards),
+ backend, db);
+ // Notify the PDM about the conversion being completed.
+ backend->NotifyOfAddressConversionCompleted();
+ return WebDatabase::COMMIT_NEEDED;
+ }
+
+ // We need to notify the PDM even if we do not change any data (it relies on
+ // it to refresh its local view).
+ backend->NotifyOfAddressConversionCompleted();
+ return WebDatabase::COMMIT_NOT_NEEDED;
+}
+
+} // namespace util
+} // namespace autofill
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.h
new file mode 100644
index 00000000000..7c0d07e637d
--- /dev/null
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_backend_util.h
@@ -0,0 +1,27 @@
+// 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_WEBDATA_AUTOFILL_WEBDATA_BACKEND_UTIL_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WEBDATA_BACKEND_UTIL_H_
+
+#include "components/webdata/common/web_database.h"
+
+namespace autofill {
+
+class AutofillWebDataBackendImpl;
+
+namespace util {
+
+// Converts server profiles to local profiles. The task only converts profiles
+// that have not been converted before.
+WebDatabase::State ConvertWalletAddressesAndUpdateWalletCards(
+ const std::string& app_locale,
+ const std::string& primary_account_email,
+ AutofillWebDataBackendImpl* backend,
+ WebDatabase* db);
+
+} // namespace util
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WEBDATA_BACKEND_UTIL_H_
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc
index ebb033556c9..007d48f6809 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.cc
@@ -39,12 +39,17 @@ AutofillWebDataService::AutofillWebDataService(
base::Closure on_changed_callback =
Bind(&AutofillWebDataService::NotifyAutofillMultipleChangedOnUISequence,
weak_ptr_factory_.GetWeakPtr());
+ base::Closure on_address_conversion_completed_callback =
+ Bind(&AutofillWebDataService::
+ NotifyAutofillAddressConversionCompletedOnUISequence,
+ weak_ptr_factory_.GetWeakPtr());
base::Callback<void(syncer::ModelType)> on_sync_started_callback =
Bind(&AutofillWebDataService::NotifySyncStartedOnUISequence,
weak_ptr_factory_.GetWeakPtr());
autofill_backend_ = new AutofillWebDataBackendImpl(
wdbs_->GetBackend(), ui_task_runner_, db_task_runner_,
- on_changed_callback, on_sync_started_callback);
+ on_changed_callback, on_address_conversion_completed_callback,
+ on_sync_started_callback);
}
AutofillWebDataService::AutofillWebDataService(
@@ -60,6 +65,7 @@ AutofillWebDataService::AutofillWebDataService(
ui_task_runner_,
db_task_runner_,
base::Closure(),
+ base::Closure(),
base::Callback<void(syncer::ModelType)>())),
weak_ptr_factory_(this) {}
@@ -141,6 +147,15 @@ WebDataServiceBase::Handle AutofillWebDataService::GetServerProfiles(
consumer);
}
+void AutofillWebDataService::ConvertWalletAddressesAndUpdateWalletCards(
+ const std::string& app_locale,
+ const std::string& primary_account_email) {
+ wdbs_->ScheduleDBTask(
+ FROM_HERE, Bind(&AutofillWebDataBackendImpl::
+ ConvertWalletAddressesAndUpdateWalletCards,
+ autofill_backend_, app_locale, primary_account_email));
+}
+
WebDataServiceBase::Handle
AutofillWebDataService::GetCountOfValuesContainedBetween(
const Time& begin, const Time& end, WebDataServiceConsumer* consumer) {
@@ -336,7 +351,14 @@ AutofillWebDataService::~AutofillWebDataService() {
void AutofillWebDataService::NotifyAutofillMultipleChangedOnUISequence() {
DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
for (auto& ui_observer : ui_observer_list_)
- ui_observer.AutofillMultipleChanged();
+ ui_observer.AutofillMultipleChangedBySync();
+}
+
+void AutofillWebDataService::
+ NotifyAutofillAddressConversionCompletedOnUISequence() {
+ DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
+ for (auto& ui_observer : ui_observer_list_)
+ ui_observer.AutofillAddressConversionCompleted();
}
void AutofillWebDataService::NotifySyncStartedOnUISequence(
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h
index f25b3b0cf35..f82e891ec5d 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service.h
@@ -13,7 +13,6 @@
#include "base/observer_list.h"
#include "base/supports_user_data.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
-#include "components/autofill/core/browser/webdata/autofill_webdata.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/sync/base/model_type.h"
#include "components/webdata/common/web_data_results.h"
@@ -38,8 +37,7 @@ class AutofillWebDataServiceObserverOnUISequence;
class CreditCard;
// API for Autofill web data.
-class AutofillWebDataService : public AutofillWebData,
- public WebDataServiceBase {
+class AutofillWebDataService : public WebDataServiceBase {
public:
AutofillWebDataService(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
@@ -53,72 +51,122 @@ class AutofillWebDataService : public AutofillWebData,
// WebDataServiceBase implementation.
void ShutdownOnUISequence() override;
- // AutofillWebData implementation.
- void AddFormFields(const std::vector<FormFieldData>& fields) override;
- WebDataServiceBase::Handle GetFormValuesForElementName(
+ // Schedules a task to add form fields to the web database.
+ virtual void AddFormFields(const std::vector<FormFieldData>& fields);
+
+ // Initiates the request for a vector of values which have been entered in
+ // form input fields named |name|. The method OnWebDataServiceRequestDone of
+ // |consumer| gets called back when the request is finished, with the vector
+ // included in the argument |result|.
+ virtual WebDataServiceBase::Handle GetFormValuesForElementName(
const base::string16& name,
const base::string16& prefix,
int limit,
- WebDataServiceConsumer* consumer) override;
+ WebDataServiceConsumer* consumer);
+ // Removes form elements recorded for Autocomplete from the database.
void RemoveFormElementsAddedBetween(const base::Time& delete_begin,
- const base::Time& delete_end) override;
+ const base::Time& delete_end);
void RemoveFormValueForElementName(const base::string16& name,
- const base::string16& value) override;
+ const base::string16& value);
- // Profiles.
- void AddAutofillProfile(const AutofillProfile& profile) override;
- void UpdateAutofillProfile(const AutofillProfile& profile) override;
- void RemoveAutofillProfile(const std::string& guid) override;
- WebDataServiceBase::Handle GetAutofillProfiles(
- WebDataServiceConsumer* consumer) override;
+ // Schedules a task to add an Autofill profile to the web database.
+ void AddAutofillProfile(const AutofillProfile& profile);
+
+ // Schedules a task to update an Autofill profile in the web database.
+ void UpdateAutofillProfile(const AutofillProfile& profile);
+
+ // Schedules a task to remove an Autofill profile from the web database.
+ // |guid| is the identifier of the profile to remove.
+ void RemoveAutofillProfile(const std::string& guid);
- // Server profiles.
+ // Initiates the request for local/server Autofill profiles. The method
+ // OnWebDataServiceRequestDone of |consumer| gets called when the request is
+ // finished, with the profiles included in the argument |result|. The
+ WebDataServiceBase::Handle GetAutofillProfiles(
+ WebDataServiceConsumer* consumer);
WebDataServiceBase::Handle GetServerProfiles(
- WebDataServiceConsumer* consumer) override;
+ WebDataServiceConsumer* consumer);
+ // Schedules a task to convert server profiles to local profiles, comparing
+ // profiles using |app_locale| and filling in |primary_account_email| into
+ // newly converted profiles. The task only converts profiles that have not
+ // been converted before.
+ void ConvertWalletAddressesAndUpdateWalletCards(
+ const std::string& app_locale,
+ const std::string& primary_account_email);
+
+ // Schedules a task to count the number of unique autofill values contained
+ // in the time interval [|begin|, |end|). |begin| and |end| can be null
+ // to indicate no time limitation.
WebDataServiceBase::Handle GetCountOfValuesContainedBetween(
const base::Time& begin,
const base::Time& end,
- WebDataServiceConsumer* consumer) override;
+ WebDataServiceConsumer* consumer);
+
+ // Schedules a task to update autofill entries in the web database.
void UpdateAutofillEntries(
- const std::vector<AutofillEntry>& autofill_entries) override;
+ const std::vector<AutofillEntry>& autofill_entries);
void SetAutofillProfileChangedCallback(
base::RepeatingCallback<void(const AutofillProfileDeepChange&)>
change_cb);
- // Credit cards.
- void AddCreditCard(const CreditCard& credit_card) override;
- void UpdateCreditCard(const CreditCard& credit_card) override;
- void RemoveCreditCard(const std::string& guid) override;
- void AddFullServerCreditCard(const CreditCard& credit_card) override;
- WebDataServiceBase::Handle GetCreditCards(
- WebDataServiceConsumer* consumer) override;
+ // Schedules a task to add credit card to the web database.
+ void AddCreditCard(const CreditCard& credit_card);
- // Server cards.
+ // Schedules a task to update credit card in the web database.
+ void UpdateCreditCard(const CreditCard& credit_card);
+
+ // Schedules a task to remove a credit card from the web database.
+ // |guid| is identifier of the credit card to remove.
+ void RemoveCreditCard(const std::string& guid);
+
+ // Schedules a task to add a full server credit card to the web database.
+ void AddFullServerCreditCard(const CreditCard& credit_card);
+
+ // Initiates the request for local/server credit cards. The method
+ // OnWebDataServiceRequestDone of |consumer| gets called when the request is
+ // finished, with the credit cards included in the argument |result|. The
+ // consumer owns the credit cards.
+ WebDataServiceBase::Handle GetCreditCards(WebDataServiceConsumer* consumer);
WebDataServiceBase::Handle GetServerCreditCards(
- WebDataServiceConsumer* consumer) override;
+ WebDataServiceConsumer* consumer);
+
+ // Toggles the record for a server credit card between masked (only last 4
+ // digits) and full (all digits).
void UnmaskServerCreditCard(const CreditCard& card,
- const base::string16& full_number) override;
- void MaskServerCreditCard(const std::string& id) override;
+ const base::string16& full_number);
+ void MaskServerCreditCard(const std::string& id);
- // PaymentsCustomerData.
+ // Initiates the request for Payments customer data. The method
+ // OnWebDataServiceRequestDone of |consumer| gets called when the request is
+ // finished, with the customer data included in the argument |result|. The
+ // consumer owns the data.
WebDataServiceBase::Handle GetPaymentsCustomerData(
- WebDataServiceConsumer* consumer) override;
+ WebDataServiceConsumer* consumer);
void ClearAllServerData();
void ClearAllLocalData();
- void UpdateServerCardMetadata(const CreditCard& credit_card) override;
- void UpdateServerAddressMetadata(const AutofillProfile& profile) override;
+ // Updates the metadata for a server card (masked or not).
+ void UpdateServerCardMetadata(const CreditCard& credit_card);
+
+ // Updates the metadata for a server address.
+ void UpdateServerAddressMetadata(const AutofillProfile& profile);
+ // Removes Autofill records from the database.
void RemoveAutofillDataModifiedBetween(const base::Time& delete_begin,
- const base::Time& delete_end) override;
+ const base::Time& delete_end);
+
+ // Removes origin URLs associated with Autofill profiles and credit cards from
+ // the database.
void RemoveOriginURLsModifiedBetween(const base::Time& delete_begin,
- const base::Time& delete_end) override;
+ const base::Time& delete_end);
- void RemoveOrphanAutofillTableRows() override;
+ // Removes the orphan rows in the autofill_profile_names,
+ // autofill_profile_emails and autofill_profile_phones tables.
+ void RemoveOrphanAutofillTableRows();
void AddObserver(AutofillWebDataServiceObserverOnDBSequence* observer);
void RemoveObserver(AutofillWebDataServiceObserverOnDBSequence* observer);
@@ -150,9 +198,9 @@ class AutofillWebDataService : public AutofillWebData,
protected:
~AutofillWebDataService() override;
- virtual void NotifyAutofillMultipleChangedOnUISequence();
-
- virtual void NotifySyncStartedOnUISequence(syncer::ModelType model_type);
+ void NotifyAutofillMultipleChangedOnUISequence();
+ void NotifyAutofillAddressConversionCompletedOnUISequence();
+ void NotifySyncStartedOnUISequence(syncer::ModelType model_type);
base::WeakPtr<AutofillWebDataService> AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
diff --git a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h
index 7477ce7781b..7fd955e98cc 100644
--- a/chromium/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h
+++ b/chromium/components/autofill/core/browser/webdata/autofill_webdata_service_observer.h
@@ -25,7 +25,10 @@ class AutofillWebDataServiceObserverOnDBSequence {
// Called on DB sequence when multiple Autofill entries have been modified by
// Sync.
- virtual void AutofillMultipleChanged() {}
+ // TODO(crbug.com/900607): Remove AutofillMultipleChangedBySync() from
+ // AutofillWebDataServiceObserverOnDBSequence once USS for wallet_metadata
+ // launches.
+ virtual void AutofillMultipleChangedBySync() {}
protected:
virtual ~AutofillWebDataServiceObserverOnDBSequence() {}
@@ -35,7 +38,9 @@ class AutofillWebDataServiceObserverOnUISequence {
public:
// Called on UI sequence when multiple Autofill entries have been modified by
// Sync.
- virtual void AutofillMultipleChanged() {}
+ virtual void AutofillMultipleChangedBySync() {}
+
+ virtual void AutofillAddressConversionCompleted() {}
virtual void AutofillProfileChanged(const AutofillProfileChange& change) {}
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 3368878abf0..53189231a80 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
@@ -32,6 +32,7 @@ class MockAutofillWebDataBackend : public AutofillWebDataBackend {
void(const AutofillProfileChange& change));
MOCK_METHOD1(NotifyOfCreditCardChanged, void(const CreditCardChange& change));
MOCK_METHOD0(NotifyOfMultipleAutofillChanges, void());
+ MOCK_METHOD0(NotifyOfAddressConversionCompleted, void());
MOCK_METHOD1(NotifyThatSyncHasStarted, void(syncer::ModelType model_type));
private:
diff --git a/chromium/components/autofill/core/browser/webdata/web_data_service_unittest.cc b/chromium/components/autofill/core/browser/webdata/web_data_service_unittest.cc
index f1d6e76fcc9..b7503bca43f 100644
--- a/chromium/components/autofill/core/browser/webdata/web_data_service_unittest.cc
+++ b/chromium/components/autofill/core/browser/webdata/web_data_service_unittest.cc
@@ -17,7 +17,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/post_task.h"
-#include "base/task/task_scheduler/task_scheduler.h"
+#include "base/task/thread_pool/thread_pool.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -153,7 +153,7 @@ class WebDataServiceAutofillTest : public WebDataServiceTest {
&AutofillWebDataService::AddObserver;
wds_->GetDBTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(add_observer_func, wds_, &observer_));
- base::TaskScheduler::GetInstance()->FlushForTesting();
+ base::ThreadPool::GetInstance()->FlushForTesting();
}
void TearDown() override {
@@ -313,7 +313,7 @@ TEST_F(WebDataServiceAutofillTest, ProfileRemove) {
// Check that GUID-based notification was sent.
const AutofillProfileChange expected_change(AutofillProfileChange::REMOVE,
- profile.guid(), nullptr);
+ profile.guid(), &profile);
EXPECT_CALL(observer_, AutofillProfileChanged(expected_change))
.WillOnce(SignalEvent(&done_event_));
@@ -491,7 +491,7 @@ TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) {
// Check that GUID-based notification was sent for the profile.
const AutofillProfileChange expected_profile_change(
- AutofillProfileChange::REMOVE, profile.guid(), nullptr);
+ AutofillProfileChange::REMOVE, profile.guid(), &profile);
EXPECT_CALL(observer_, AutofillProfileChanged(expected_profile_change))
.WillOnce(SignalEvent(&done_event_));